summaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2014-03-20 14:49:19 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2014-03-20 14:49:19 +0000
commitda82fd65effce44be0da4142490d559d404a7c7a (patch)
treea1ca62c7eddba140fb9ba8d3f5434100de5076af /main
parenta09553ac6c535ce804805e7f143d7daa932efa25 (diff)
downloadaports-da82fd65effce44be0da4142490d559d404a7c7a.tar.bz2
aports-da82fd65effce44be0da4142490d559d404a7c7a.tar.xz
main/linux-scst: deleted
obsolete
Diffstat (limited to 'main')
-rw-r--r--main/linux-scst/APKBUILD137
-rw-r--r--main/linux-scst/kernelconfig.x86_645318
-rw-r--r--main/linux-scst/scst-2.2.0-3.2.2.patch80901
3 files changed, 0 insertions, 86356 deletions
diff --git a/main/linux-scst/APKBUILD b/main/linux-scst/APKBUILD
deleted file mode 100644
index 4876bc105..000000000
--- a/main/linux-scst/APKBUILD
+++ /dev/null
@@ -1,137 +0,0 @@
-# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
-
-_flavor=scst
-pkgname=linux-${_flavor}
-pkgver=3.2.2
-
-_scstver=2.2.0
-
-if [ "${pkgver##*.*.*}" = "$pkgver" ]; then
- _kernver=$pkgver
-else
- _kernver=${pkgver%.*}
-fi
-
-pkgrel=1
-pkgdesc="Linux kernel with SCST"
-url="http://scst.sourceforge.net"
-depends="mkinitfs linux-firmware"
-makedepends="perl sed installkernel"
-options="!strip"
-_config=${config:-kernelconfig.${CARCH}}
-install=
-source="http://www.kernel.org/pub/linux/kernel/v3.0/linux-$_kernver.tar.bz2
- http://www.kernel.org/pub/linux/kernel/v3.0/patch-$pkgver.bz2
- kernelconfig.x86_64
- scst-2.2.0-3.2.2.patch
- "
-subpackages="$pkgname-dev"
-arch="x86_64"
-license="GPL-2"
-
-_abi_release=${pkgver}-${_scstver}
-
-prepare() {
- cd "$srcdir"/linux-$_kernver
- if [ "$_kernver" != "$pkgver" ]; then
- bunzip2 -c < ../patch-$pkgver.bz2 | patch -p1 -N || return 1
- fi
-
- # first apply patches in specified order
- for i in $source; do
- i=${i##*/}
- case $i in
- *.patch|*.diff)
- msg "Applying $i..."
- patch -s -p1 -i "$srcdir"/$i || return 1
- ;;
- esac
- done
-
- mkdir -p "$srcdir"/build
- cp "$srcdir"/$_config "$srcdir"/build/.config || return 1
- make -C "$srcdir"/linux-$_kernver O="$srcdir"/build HOSTCC="${CC:-gcc}" \
- silentoldconfig
-}
-
-# this is so we can do: 'abuild menuconfig' to reconfigure kernel
-menuconfig() {
- cd "$srcdir"/build
- make menuconfig
- cp .config "$startdir"/$_config || return 1
-}
-
-build() {
- cd "$srcdir"/build
- export GCC_SPECS=hardenednopie.specs
- make CC="${CC:-gcc}" \
- KBUILD_BUILD_VERSION="$((pkgrel + 1 ))-Alpine" \
- || return 1
-}
-
-package() {
- cd "$srcdir"/build
- mkdir -p "$pkgdir"/boot "$pkgdir"/lib/modules
- make -j1 modules_install install \
- INSTALL_MOD_PATH="$pkgdir" \
- INSTALL_PATH="$pkgdir"/boot \
- || return 1
-
- rm -rf "$pkgdir"/lib/modules/*/build \
- "$pkgdir"/lib/modules/*/source
- rm -rf "$pkgdir"/lib/firmware
-
- install -D include/config/kernel.release \
- "$pkgdir"/usr/share/kernel/$_flavor/kernel.release
-}
-
-dev() {
- # copy the only the parts that we really need for build 3rd party
- # kernel modules and install those as /usr/src/linux-headers,
- # simlar to what ubuntu does
- #
- # this way you dont need to install the 300-400 kernel sources to
- # build a tiny kernel module
- #
- pkgdesc="Headers and script for third party modules for kernel"
- local dir="$subpkgdir"/usr/src/linux-headers-${_abi_release}
-
- # first we import config, run prepare to set up for building
- # external modules, and create the scripts
- mkdir -p "$dir"
- cp "$srcdir"/$_config "$dir"/.config
- make -j1 -C "$srcdir"/linux-$_kernver O="$dir" HOSTCC="${CC:-gcc}" \
- silentoldconfig prepare scripts
-
- # remove the stuff that poits to real sources. we want 3rd party
- # modules to believe this is the soruces
- rm "$dir"/Makefile "$dir"/source
-
- # copy the needed stuff from real sources
- #
- # this is taken from ubuntu kernel build script
- # http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-jaunty.git;a=blob;f=debian/rules.d/3-binary-indep.mk;hb=HEAD
- cd "$srcdir"/linux-$_kernver
- find . -path './include/*' -prune -o -path './scripts/*' -prune \
- -o -type f \( -name 'Makefile*' -o -name 'Kconfig*' \
- -o -name 'Kbuild*' -o -name '*.sh' -o -name '*.pl' \
- -o -name '*.lds' \) | cpio -pdm "$dir"
- cp -a drivers/media/dvb/dvb-core/*.h "$dir"/drivers/media/dvb/dvb-core
- cp -a drivers/media/video/*.h "$dir"/drivers/media/video
- cp -a drivers/media/dvb/frontends/*.h "$dir"/drivers/media/dvb/frontends
- cp -a scripts include "$dir"
- find $(find arch -name include -type d -print) -type f \
- | cpio -pdm "$dir"
-
- install -Dm644 "$srcdir"/build/Module.symvers \
- "$dir"/Module.symvers
-
- mkdir -p "$subpkgdir"/lib/modules/${_abi_release}
- ln -sf /usr/src/linux-headers-${_abi_release} \
- "$subpkgdir"/lib/modules/${_abi_release}/build
-}
-
-md5sums="7ceb61f87c097fc17509844b71268935 linux-3.2.tar.bz2
-e9e53fba37c5e2afa4cdecab234120bd patch-3.2.2.bz2
-ef1fc8a0f776a9639a135ac58acd26ce kernelconfig.x86_64
-7fc262466073cc46e51630a2ca55eada scst-2.2.0-3.2.2.patch"
diff --git a/main/linux-scst/kernelconfig.x86_64 b/main/linux-scst/kernelconfig.x86_64
deleted file mode 100644
index 117c48e29..000000000
--- a/main/linux-scst/kernelconfig.x86_64
+++ /dev/null
@@ -1,5318 +0,0 @@
-#
-# Automatically generated file; DO NOT EDIT.
-# Linux/x86_64 3.2.2 Kernel Configuration
-#
-CONFIG_64BIT=y
-# CONFIG_X86_32 is not set
-CONFIG_X86_64=y
-CONFIG_X86=y
-CONFIG_INSTRUCTION_DECODER=y
-CONFIG_OUTPUT_FORMAT="elf64-x86-64"
-CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_CLOCKSOURCE_WATCHDOG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_MMU=y
-CONFIG_ZONE_DMA=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_ARCH_MAY_HAVE_PC_FDC=y
-# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_ARCH_HAS_CPU_RELAX=y
-CONFIG_ARCH_HAS_DEFAULT_IDLE=y
-CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
-CONFIG_HAVE_SETUP_PER_CPU_AREA=y
-CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
-CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ZONE_DMA32=y
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_AUDIT_ARCH=y
-CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
-CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
-CONFIG_HAVE_INTEL_TXT=y
-CONFIG_X86_64_SMP=y
-CONFIG_X86_HT=y
-CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
-# CONFIG_KTIME_SCALAR is not set
-CONFIG_ARCH_CPU_PROBE_RELEASE=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_IRQ_WORK=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_CROSS_COMPILE=""
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_BZIP2=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_XZ=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_BZIP2 is not set
-# CONFIG_KERNEL_LZMA is not set
-# CONFIG_KERNEL_XZ is not set
-# CONFIG_KERNEL_LZO is not set
-CONFIG_DEFAULT_HOSTNAME="(none)"
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-# CONFIG_FHANDLE is not set
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-# CONFIG_AUDIT is not set
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-
-#
-# IRQ subsystem
-#
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_HAVE_SPARSE_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_PENDING_IRQ=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_SPARSE_IRQ=y
-
-#
-# RCU Subsystem
-#
-CONFIG_TREE_RCU=y
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_RCU_TRACE is not set
-CONFIG_RCU_FANOUT=32
-# CONFIG_RCU_FANOUT_EXACT is not set
-CONFIG_RCU_FAST_NO_HZ=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_IKCONFIG=m
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
-CONFIG_CGROUPS=y
-# CONFIG_CGROUP_DEBUG is not set
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_DEVICE=y
-CONFIG_CPUSETS=y
-# CONFIG_PROC_PID_CPUSET is not set
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
-# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
-# CONFIG_CGROUP_PERF is not set
-CONFIG_CGROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_BLK_CGROUP=y
-# CONFIG_DEBUG_BLK_CGROUP is not set
-CONFIG_NAMESPACES=y
-CONFIG_UTS_NS=y
-CONFIG_IPC_NS=y
-CONFIG_USER_NS=y
-CONFIG_PID_NS=y
-CONFIG_NET_NS=y
-CONFIG_SCHED_AUTOGROUP=y
-CONFIG_MM_OWNER=y
-# CONFIG_SYSFS_DEPRECATED is not set
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_LZMA=y
-CONFIG_RD_XZ=y
-CONFIG_RD_LZO=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_EXPERT=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_PCSPKR_PLATFORM=y
-CONFIG_HAVE_PCSPKR_PLATFORM=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_EMBEDDED=y
-CONFIG_HAVE_PERF_EVENTS=y
-
-#
-# Kernel Performance Events And Counters
-#
-CONFIG_PERF_EVENTS=y
-CONFIG_PERF_COUNTERS=y
-# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-# CONFIG_SLUB_DEBUG is not set
-# CONFIG_COMPAT_BRK is not set
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set
-CONFIG_HAVE_OPROFILE=y
-CONFIG_KPROBES=y
-# CONFIG_JUMP_LABEL is not set
-CONFIG_OPTPROBES=y
-CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
-CONFIG_KRETPROBES=y
-CONFIG_USER_RETURN_NOTIFIER=y
-CONFIG_HAVE_IOREMAP_PROT=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_OPTPROBES=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_USE_GENERIC_SMP_HELPERS=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_HW_BREAKPOINT=y
-CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
-CONFIG_HAVE_USER_RETURN_NOTIFIER=y
-CONFIG_HAVE_PERF_EVENTS_NMI=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
-
-#
-# GCOV-based kernel profiling
-#
-# CONFIG_GCOV_KERNEL is not set
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_STOP_MACHINE=y
-CONFIG_BLOCK=y
-CONFIG_BLK_DEV_BSG=y
-CONFIG_BLK_DEV_BSGLIB=y
-# CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_DEV_THROTTLING is not set
-CONFIG_BLOCK_COMPAT=y
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_DEADLINE=m
-CONFIG_IOSCHED_CFQ=y
-CONFIG_CFQ_GROUP_IOSCHED=y
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_PREEMPT_NOTIFIERS=y
-CONFIG_PADATA=y
-# CONFIG_INLINE_SPIN_TRYLOCK is not set
-# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK is not set
-# CONFIG_INLINE_SPIN_LOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
-CONFIG_INLINE_SPIN_UNLOCK=y
-# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
-CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
-# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_READ_TRYLOCK is not set
-# CONFIG_INLINE_READ_LOCK is not set
-# CONFIG_INLINE_READ_LOCK_BH is not set
-# CONFIG_INLINE_READ_LOCK_IRQ is not set
-# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
-CONFIG_INLINE_READ_UNLOCK=y
-# CONFIG_INLINE_READ_UNLOCK_BH is not set
-CONFIG_INLINE_READ_UNLOCK_IRQ=y
-# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_WRITE_TRYLOCK is not set
-# CONFIG_INLINE_WRITE_LOCK is not set
-# CONFIG_INLINE_WRITE_LOCK_BH is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
-CONFIG_INLINE_WRITE_UNLOCK=y
-# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
-CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
-# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_FREEZER=y
-
-#
-# Processor type and features
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
-CONFIG_SMP=y
-CONFIG_X86_X2APIC=y
-CONFIG_X86_MPPARSE=y
-CONFIG_X86_EXTENDED_PLATFORM=y
-# CONFIG_X86_VSMP is not set
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
-CONFIG_PARAVIRT_GUEST=y
-# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
-CONFIG_XEN=y
-CONFIG_XEN_DOM0=y
-CONFIG_XEN_PRIVILEGED_GUEST=y
-CONFIG_XEN_PVHVM=y
-CONFIG_XEN_MAX_DOMAIN_MEMORY=128
-CONFIG_XEN_SAVE_RESTORE=y
-# CONFIG_XEN_DEBUG_FS is not set
-CONFIG_KVM_CLOCK=y
-CONFIG_KVM_GUEST=y
-CONFIG_PARAVIRT=y
-# CONFIG_PARAVIRT_SPINLOCKS is not set
-CONFIG_PARAVIRT_CLOCK=y
-# CONFIG_PARAVIRT_DEBUG is not set
-CONFIG_NO_BOOTMEM=y
-# CONFIG_MEMTEST is not set
-# CONFIG_MK8 is not set
-# CONFIG_MPSC is not set
-# CONFIG_MCORE2 is not set
-# CONFIG_MATOM is not set
-CONFIG_GENERIC_CPU=y
-CONFIG_X86_INTERNODE_CACHE_SHIFT=6
-CONFIG_X86_CMPXCHG=y
-CONFIG_CMPXCHG_LOCAL=y
-CONFIG_CMPXCHG_DOUBLE=y
-CONFIG_X86_L1_CACHE_SHIFT=6
-CONFIG_X86_XADD=y
-CONFIG_X86_WP_WORKS_OK=y
-CONFIG_X86_TSC=y
-CONFIG_X86_CMPXCHG64=y
-CONFIG_X86_CMOV=y
-CONFIG_X86_MINIMUM_CPU_FAMILY=64
-CONFIG_X86_DEBUGCTLMSR=y
-# CONFIG_PROCESSOR_SELECT is not set
-CONFIG_CPU_SUP_INTEL=y
-CONFIG_CPU_SUP_AMD=y
-CONFIG_CPU_SUP_CENTAUR=y
-CONFIG_HPET_TIMER=y
-CONFIG_HPET_EMULATE_RTC=y
-CONFIG_DMI=y
-CONFIG_GART_IOMMU=y
-# CONFIG_CALGARY_IOMMU is not set
-CONFIG_SWIOTLB=y
-CONFIG_IOMMU_HELPER=y
-# CONFIG_MAXSMP is not set
-CONFIG_NR_CPUS=128
-CONFIG_SCHED_SMT=y
-CONFIG_SCHED_MC=y
-CONFIG_IRQ_TIME_ACCOUNTING=y
-# CONFIG_PREEMPT_NONE is not set
-CONFIG_PREEMPT_VOLUNTARY=y
-# CONFIG_PREEMPT is not set
-CONFIG_X86_LOCAL_APIC=y
-CONFIG_X86_IO_APIC=y
-# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
-# CONFIG_X86_MCE is not set
-CONFIG_I8K=m
-CONFIG_MICROCODE=m
-CONFIG_MICROCODE_INTEL=y
-CONFIG_MICROCODE_AMD=y
-CONFIG_MICROCODE_OLD_INTERFACE=y
-CONFIG_X86_MSR=m
-CONFIG_X86_CPUID=m
-CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_DIRECT_GBPAGES=y
-# CONFIG_NUMA is not set
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_SPARSEMEM_MANUAL=y
-CONFIG_SPARSEMEM=y
-CONFIG_HAVE_MEMORY_PRESENT=y
-CONFIG_SPARSEMEM_EXTREME=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
-CONFIG_SPARSEMEM_VMEMMAP=y
-CONFIG_HAVE_MEMBLOCK=y
-# CONFIG_MEMORY_HOTPLUG is not set
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_COMPACTION=y
-CONFIG_MIGRATION=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_MMU_NOTIFIER=y
-CONFIG_KSM=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
-CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
-# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set
-# CONFIG_CLEANCACHE is not set
-# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
-CONFIG_X86_RESERVE_LOW=64
-CONFIG_MTRR=y
-CONFIG_MTRR_SANITIZER=y
-CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
-CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
-CONFIG_X86_PAT=y
-CONFIG_ARCH_USES_PG_UNCACHED=y
-CONFIG_ARCH_RANDOM=y
-# CONFIG_EFI is not set
-# CONFIG_SECCOMP is not set
-# CONFIG_CC_STACKPROTECTOR is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_250 is not set
-CONFIG_HZ_300=y
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=300
-CONFIG_SCHED_HRTICK=y
-# CONFIG_KEXEC is not set
-# CONFIG_CRASH_DUMP is not set
-CONFIG_PHYSICAL_START=0x1000000
-# CONFIG_RELOCATABLE is not set
-CONFIG_PHYSICAL_ALIGN=0x1000000
-CONFIG_HOTPLUG_CPU=y
-# CONFIG_COMPAT_VDSO is not set
-# CONFIG_CMDLINE_BOOL is not set
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-
-#
-# Power management and ACPI options
-#
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_HIBERNATE_CALLBACKS=y
-# CONFIG_HIBERNATION is not set
-CONFIG_PM_SLEEP=y
-CONFIG_PM_SLEEP_SMP=y
-# CONFIG_PM_RUNTIME is not set
-CONFIG_PM=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_ACPI=y
-CONFIG_ACPI_SLEEP=y
-CONFIG_ACPI_PROCFS=y
-CONFIG_ACPI_PROCFS_POWER=y
-CONFIG_ACPI_EC_DEBUGFS=y
-CONFIG_ACPI_PROC_EVENT=y
-CONFIG_ACPI_AC=m
-CONFIG_ACPI_BATTERY=m
-CONFIG_ACPI_BUTTON=m
-CONFIG_ACPI_VIDEO=m
-CONFIG_ACPI_FAN=m
-CONFIG_ACPI_DOCK=y
-CONFIG_ACPI_PROCESSOR=m
-CONFIG_ACPI_IPMI=m
-CONFIG_ACPI_HOTPLUG_CPU=y
-# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set
-CONFIG_ACPI_THERMAL=m
-# CONFIG_ACPI_CUSTOM_DSDT is not set
-CONFIG_ACPI_BLACKLIST_YEAR=0
-# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_PCI_SLOT=m
-CONFIG_X86_PM_TIMER=y
-CONFIG_ACPI_CONTAINER=m
-CONFIG_ACPI_SBS=m
-CONFIG_ACPI_HED=m
-# CONFIG_ACPI_CUSTOM_METHOD is not set
-CONFIG_ACPI_APEI=y
-# CONFIG_ACPI_APEI_GHES is not set
-CONFIG_ACPI_APEI_EINJ=m
-CONFIG_ACPI_APEI_ERST_DEBUG=y
-# CONFIG_SFI is not set
-
-#
-# CPU Frequency scaling
-#
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_TABLE=m
-CONFIG_CPU_FREQ_STAT=m
-# CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=m
-CONFIG_CPU_FREQ_GOV_USERSPACE=m
-CONFIG_CPU_FREQ_GOV_ONDEMAND=m
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
-
-#
-# x86 CPU frequency scaling drivers
-#
-CONFIG_X86_PCC_CPUFREQ=m
-CONFIG_X86_ACPI_CPUFREQ=m
-CONFIG_X86_POWERNOW_K8=m
-CONFIG_X86_SPEEDSTEP_CENTRINO=m
-CONFIG_X86_P4_CLOCKMOD=m
-
-#
-# shared options
-#
-CONFIG_X86_SPEEDSTEP_LIB=m
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_INTEL_IDLE=y
-
-#
-# Memory power savings
-#
-CONFIG_I7300_IDLE_IOAT_CHANNEL=y
-CONFIG_I7300_IDLE=m
-
-#
-# Bus options (PCI etc.)
-#
-CONFIG_PCI=y
-CONFIG_PCI_DIRECT=y
-CONFIG_PCI_MMCONFIG=y
-CONFIG_PCI_XEN=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_CNB20LE_QUIRK=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_HOTPLUG_PCI_PCIE=m
-# CONFIG_PCIEAER is not set
-CONFIG_PCIEASPM=y
-# CONFIG_PCIEASPM_DEBUG is not set
-CONFIG_ARCH_SUPPORTS_MSI=y
-CONFIG_PCI_MSI=y
-# CONFIG_PCI_DEBUG is not set
-CONFIG_PCI_STUB=m
-CONFIG_XEN_PCIDEV_FRONTEND=m
-CONFIG_HT_IRQ=y
-CONFIG_PCI_ATS=y
-CONFIG_PCI_IOV=y
-CONFIG_PCI_PRI=y
-CONFIG_PCI_PASID=y
-CONFIG_PCI_IOAPIC=y
-CONFIG_PCI_LABEL=y
-CONFIG_ISA_DMA_API=y
-CONFIG_AMD_NB=y
-CONFIG_PCCARD=m
-CONFIG_PCMCIA=m
-CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_CARDBUS=y
-
-#
-# PC-card bridges
-#
-CONFIG_YENTA=m
-CONFIG_YENTA_O2=y
-CONFIG_YENTA_RICOH=y
-CONFIG_YENTA_TI=y
-CONFIG_YENTA_ENE_TUNE=y
-CONFIG_YENTA_TOSHIBA=y
-CONFIG_PD6729=m
-CONFIG_I82092=m
-CONFIG_PCCARD_NONSTATIC=y
-CONFIG_HOTPLUG_PCI=m
-CONFIG_HOTPLUG_PCI_FAKE=m
-CONFIG_HOTPLUG_PCI_ACPI=m
-CONFIG_HOTPLUG_PCI_ACPI_IBM=m
-CONFIG_HOTPLUG_PCI_CPCI=y
-CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m
-CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m
-CONFIG_HOTPLUG_PCI_SHPC=m
-# CONFIG_RAPIDIO is not set
-
-#
-# Executable file formats / Emulations
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_COMPAT_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_HAVE_AOUT is not set
-CONFIG_BINFMT_MISC=m
-CONFIG_IA32_EMULATION=y
-# CONFIG_IA32_AOUT is not set
-CONFIG_COMPAT=y
-CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
-CONFIG_SYSVIPC_COMPAT=y
-CONFIG_KEYS_COMPAT=y
-CONFIG_HAVE_TEXT_POKE_SMP=y
-CONFIG_NET=y
-CONFIG_COMPAT_NETLINK_MESSAGES=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-CONFIG_XFRM_SUB_POLICY=y
-CONFIG_XFRM_MIGRATE=y
-# CONFIG_XFRM_STATISTICS is not set
-CONFIG_XFRM_IPCOMP=m
-CONFIG_NET_KEY=m
-CONFIG_NET_KEY_MIGRATE=y
-CONFIG_INET=y
-CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-# CONFIG_IP_FIB_TRIE_STATS is not set
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_ROUTE_CLASSID=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE_DEMUX=y
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
-# CONFIG_IP_PIMSM_V1 is not set
-CONFIG_IP_PIMSM_V2=y
-CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_TUNNEL=m
-CONFIG_INET_TUNNEL=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_LRO=y
-CONFIG_INET_DIAG=m
-CONFIG_INET_TCP_DIAG=m
-CONFIG_TCP_CONG_ADVANCED=y
-CONFIG_TCP_CONG_BIC=m
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_TCP_CONG_WESTWOOD=m
-CONFIG_TCP_CONG_HTCP=m
-CONFIG_TCP_CONG_HSTCP=m
-CONFIG_TCP_CONG_HYBLA=m
-CONFIG_TCP_CONG_VEGAS=m
-CONFIG_TCP_CONG_SCALABLE=m
-CONFIG_TCP_CONG_LP=m
-CONFIG_TCP_CONG_VENO=m
-CONFIG_TCP_CONG_YEAH=m
-CONFIG_TCP_CONG_ILLINOIS=m
-CONFIG_DEFAULT_CUBIC=y
-# CONFIG_DEFAULT_RENO is not set
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-CONFIG_IPV6=y
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_TUNNEL=m
-CONFIG_INET6_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_SIT_6RD=y
-CONFIG_IPV6_NDISC_NODETYPE=y
-CONFIG_IPV6_TUNNEL=m
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IPV6_MROUTE=y
-CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
-CONFIG_IPV6_PIMSM_V2=y
-# CONFIG_NETLABEL is not set
-CONFIG_NETWORK_SECMARK=y
-CONFIG_NETWORK_PHY_TIMESTAMPING=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_NETFILTER_ADVANCED=y
-CONFIG_BRIDGE_NETFILTER=y
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_MARK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_ZONES=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CONNTRACK_TIMESTAMP=y
-CONFIG_NF_CT_PROTO_DCCP=m
-CONFIG_NF_CT_PROTO_GRE=m
-CONFIG_NF_CT_PROTO_SCTP=m
-CONFIG_NF_CT_PROTO_UDPLITE=m
-CONFIG_NF_CONNTRACK_AMANDA=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_H323=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_BROADCAST=m
-CONFIG_NF_CONNTRACK_NETBIOS_NS=m
-CONFIG_NF_CONNTRACK_SNMP=m
-CONFIG_NF_CONNTRACK_PPTP=m
-CONFIG_NF_CONNTRACK_SANE=m
-CONFIG_NF_CONNTRACK_SIP=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NETFILTER_TPROXY=m
-CONFIG_NETFILTER_XTABLES=m
-
-#
-# Xtables combined modules
-#
-CONFIG_NETFILTER_XT_MARK=m
-CONFIG_NETFILTER_XT_CONNMARK=m
-CONFIG_NETFILTER_XT_SET=m
-
-#
-# Xtables targets
-#
-CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CT=m
-CONFIG_NETFILTER_XT_TARGET_DSCP=m
-CONFIG_NETFILTER_XT_TARGET_HL=m
-CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
-CONFIG_NETFILTER_XT_TARGET_LED=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
-CONFIG_NETFILTER_XT_TARGET_RATEEST=m
-CONFIG_NETFILTER_XT_TARGET_TEE=m
-CONFIG_NETFILTER_XT_TARGET_TPROXY=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
-
-#
-# Xtables matches
-#
-CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
-CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_CPU=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_HL=m
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_IPVS=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_OSF=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_SOCKET=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_IP_SET=m
-CONFIG_IP_SET_MAX=256
-CONFIG_IP_SET_BITMAP_IP=m
-CONFIG_IP_SET_BITMAP_IPMAC=m
-CONFIG_IP_SET_BITMAP_PORT=m
-CONFIG_IP_SET_HASH_IP=m
-CONFIG_IP_SET_HASH_IPPORT=m
-CONFIG_IP_SET_HASH_IPPORTIP=m
-CONFIG_IP_SET_HASH_IPPORTNET=m
-CONFIG_IP_SET_HASH_NET=m
-CONFIG_IP_SET_HASH_NETPORT=m
-CONFIG_IP_SET_HASH_NETIFACE=m
-CONFIG_IP_SET_LIST_SET=m
-CONFIG_IP_VS=m
-CONFIG_IP_VS_IPV6=y
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS transport protocol load balancing support
-#
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_AH_ESP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-CONFIG_IP_VS_PROTO_SCTP=y
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-
-#
-# IPVS application helper
-#
-CONFIG_IP_VS_FTP=m
-CONFIG_IP_VS_NFCT=y
-CONFIG_IP_VS_PE_SIP=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_DEFRAG_IPV4=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
-CONFIG_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
-CONFIG_NF_NAT_PROTO_DCCP=m
-CONFIG_NF_NAT_PROTO_GRE=m
-CONFIG_NF_NAT_PROTO_UDPLITE=m
-CONFIG_NF_NAT_PROTO_SCTP=m
-CONFIG_NF_NAT_FTP=m
-CONFIG_NF_NAT_IRC=m
-CONFIG_NF_NAT_TFTP=m
-CONFIG_NF_NAT_AMANDA=m
-CONFIG_NF_NAT_PPTP=m
-CONFIG_NF_NAT_H323=m
-CONFIG_NF_NAT_SIP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_SECURITY=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-
-#
-# IPv6: Netfilter Configuration
-#
-CONFIG_NF_DEFRAG_IPV6=m
-CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_AH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_MH=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_RAW=m
-CONFIG_IP6_NF_SECURITY=m
-
-#
-# DECnet: Netfilter Configuration
-#
-CONFIG_DECNET_NF_GRABULATOR=m
-CONFIG_BRIDGE_NF_EBTABLES=m
-CONFIG_BRIDGE_EBT_BROUTE=m
-CONFIG_BRIDGE_EBT_T_FILTER=m
-CONFIG_BRIDGE_EBT_T_NAT=m
-CONFIG_BRIDGE_EBT_802_3=m
-CONFIG_BRIDGE_EBT_AMONG=m
-CONFIG_BRIDGE_EBT_ARP=m
-CONFIG_BRIDGE_EBT_IP=m
-CONFIG_BRIDGE_EBT_IP6=m
-CONFIG_BRIDGE_EBT_LIMIT=m
-CONFIG_BRIDGE_EBT_MARK=m
-CONFIG_BRIDGE_EBT_PKTTYPE=m
-CONFIG_BRIDGE_EBT_STP=m
-CONFIG_BRIDGE_EBT_VLAN=m
-CONFIG_BRIDGE_EBT_ARPREPLY=m
-CONFIG_BRIDGE_EBT_DNAT=m
-CONFIG_BRIDGE_EBT_MARK_T=m
-CONFIG_BRIDGE_EBT_REDIRECT=m
-CONFIG_BRIDGE_EBT_SNAT=m
-CONFIG_BRIDGE_EBT_LOG=m
-CONFIG_BRIDGE_EBT_ULOG=m
-CONFIG_BRIDGE_EBT_NFLOG=m
-CONFIG_IP_DCCP=m
-CONFIG_INET_DCCP_DIAG=m
-
-#
-# DCCP CCIDs Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=y
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_TFRC_LIB=y
-
-#
-# DCCP Kernel Hacking
-#
-# CONFIG_IP_DCCP_DEBUG is not set
-# CONFIG_NET_DCCPPROBE is not set
-CONFIG_IP_SCTP=m
-CONFIG_NET_SCTPPROBE=m
-# CONFIG_SCTP_DBG_MSG is not set
-# CONFIG_SCTP_DBG_OBJCNT is not set
-# CONFIG_SCTP_HMAC_NONE is not set
-CONFIG_SCTP_HMAC_SHA1=y
-# CONFIG_SCTP_HMAC_MD5 is not set
-CONFIG_RDS=m
-# CONFIG_RDS_RDMA is not set
-# CONFIG_RDS_TCP is not set
-# CONFIG_RDS_DEBUG is not set
-CONFIG_TIPC=m
-# CONFIG_TIPC_ADVANCED is not set
-# CONFIG_TIPC_DEBUG is not set
-CONFIG_ATM=m
-CONFIG_ATM_CLIP=m
-# CONFIG_ATM_CLIP_NO_ICMP is not set
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
-CONFIG_ATM_BR2684=m
-# CONFIG_ATM_BR2684_IPFILTER is not set
-CONFIG_L2TP=m
-CONFIG_L2TP_DEBUGFS=m
-CONFIG_L2TP_V3=y
-CONFIG_L2TP_IP=m
-CONFIG_L2TP_ETH=m
-CONFIG_STP=m
-CONFIG_BRIDGE=m
-CONFIG_BRIDGE_IGMP_SNOOPING=y
-# CONFIG_NET_DSA is not set
-CONFIG_VLAN_8021Q=m
-# CONFIG_VLAN_8021Q_GVRP is not set
-CONFIG_DECNET=m
-CONFIG_DECNET_ROUTER=y
-CONFIG_LLC=m
-CONFIG_LLC2=m
-CONFIG_IPX=m
-# CONFIG_IPX_INTERN is not set
-CONFIG_ATALK=m
-CONFIG_DEV_APPLETALK=m
-CONFIG_IPDDP=m
-CONFIG_IPDDP_ENCAP=y
-CONFIG_IPDDP_DECAP=y
-CONFIG_X25=m
-CONFIG_LAPB=m
-# CONFIG_ECONET is not set
-CONFIG_WAN_ROUTER=m
-CONFIG_PHONET=m
-CONFIG_IEEE802154=m
-CONFIG_IEEE802154_6LOWPAN=m
-CONFIG_NET_SCHED=y
-
-#
-# Queueing/Scheduling
-#
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_ATM=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_MULTIQ=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFB=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_DRR=m
-CONFIG_NET_SCH_MQPRIO=m
-CONFIG_NET_SCH_CHOKE=m
-CONFIG_NET_SCH_QFQ=m
-CONFIG_NET_SCH_INGRESS=m
-
-#
-# Classification
-#
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_CLS_U32_PERF=y
-CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_FLOW=m
-# CONFIG_NET_CLS_CGROUP is not set
-CONFIG_NET_EMATCH=y
-CONFIG_NET_EMATCH_STACK=32
-CONFIG_NET_EMATCH_CMP=m
-CONFIG_NET_EMATCH_NBYTE=m
-CONFIG_NET_EMATCH_U32=m
-CONFIG_NET_EMATCH_META=m
-CONFIG_NET_EMATCH_TEXT=m
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=m
-CONFIG_NET_ACT_GACT=m
-CONFIG_GACT_PROB=y
-CONFIG_NET_ACT_MIRRED=m
-CONFIG_NET_ACT_IPT=m
-CONFIG_NET_ACT_NAT=m
-CONFIG_NET_ACT_PEDIT=m
-CONFIG_NET_ACT_SIMP=m
-CONFIG_NET_ACT_SKBEDIT=m
-CONFIG_NET_ACT_CSUM=m
-# CONFIG_NET_CLS_IND is not set
-CONFIG_NET_SCH_FIFO=y
-# CONFIG_DCB is not set
-CONFIG_DNS_RESOLVER=y
-# CONFIG_BATMAN_ADV is not set
-CONFIG_RPS=y
-CONFIG_RFS_ACCEL=y
-CONFIG_XPS=y
-CONFIG_HAVE_BPF_JIT=y
-CONFIG_BPF_JIT=y
-
-#
-# Network testing
-#
-CONFIG_NET_PKTGEN=m
-CONFIG_NET_TCPPROBE=m
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-
-#
-# Dongle support
-#
-CONFIG_DONGLE=y
-CONFIG_ESI_DONGLE=m
-CONFIG_ACTISYS_DONGLE=m
-CONFIG_TEKRAM_DONGLE=m
-CONFIG_TOIM3232_DONGLE=m
-CONFIG_LITELINK_DONGLE=m
-CONFIG_MA600_DONGLE=m
-CONFIG_GIRBIL_DONGLE=m
-CONFIG_MCP2120_DONGLE=m
-CONFIG_OLD_BELKIN_DONGLE=m
-CONFIG_ACT200L_DONGLE=m
-CONFIG_KINGSUN_DONGLE=m
-CONFIG_KSDAZZLE_DONGLE=m
-CONFIG_KS959_DONGLE=m
-
-#
-# FIR device drivers
-#
-CONFIG_USB_IRDA=m
-CONFIG_SIGMATEL_FIR=m
-CONFIG_NSC_FIR=m
-CONFIG_WINBOND_FIR=m
-CONFIG_SMC_IRCC_FIR=m
-CONFIG_ALI_FIR=m
-CONFIG_VLSI_FIR=m
-CONFIG_VIA_FIR=m
-CONFIG_MCS_FIR=m
-CONFIG_BT=m
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_CMTP=m
-CONFIG_BT_HIDP=m
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIBTUSB=m
-CONFIG_BT_HCIBTSDIO=m
-CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_ATH3K=y
-CONFIG_BT_HCIUART_LL=y
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBPA10X=m
-CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
-CONFIG_BT_HCIBTUART=m
-CONFIG_BT_HCIVHCI=m
-CONFIG_BT_MRVL=m
-CONFIG_BT_MRVL_SDIO=m
-CONFIG_BT_ATH3K=m
-CONFIG_BT_WILINK=m
-CONFIG_AF_RXRPC=m
-# CONFIG_AF_RXRPC_DEBUG is not set
-CONFIG_RXKAD=m
-CONFIG_FIB_RULES=y
-CONFIG_WIRELESS=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PROC=y
-CONFIG_WEXT_SPY=y
-CONFIG_WEXT_PRIV=y
-CONFIG_CFG80211=m
-# CONFIG_NL80211_TESTMODE is not set
-# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
-# CONFIG_CFG80211_REG_DEBUG is not set
-CONFIG_CFG80211_DEFAULT_PS=y
-# CONFIG_CFG80211_DEBUGFS is not set
-# CONFIG_CFG80211_INTERNAL_REGDB is not set
-CONFIG_CFG80211_WEXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
-CONFIG_LIB80211=m
-CONFIG_LIB80211_CRYPT_WEP=m
-CONFIG_LIB80211_CRYPT_CCMP=m
-CONFIG_LIB80211_CRYPT_TKIP=m
-# CONFIG_LIB80211_DEBUG is not set
-CONFIG_MAC80211=m
-CONFIG_MAC80211_HAS_RC=y
-CONFIG_MAC80211_RC_PID=y
-CONFIG_MAC80211_RC_MINSTREL=y
-CONFIG_MAC80211_RC_MINSTREL_HT=y
-CONFIG_MAC80211_RC_DEFAULT_PID=y
-# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
-CONFIG_MAC80211_RC_DEFAULT="pid"
-# CONFIG_MAC80211_MESH is not set
-CONFIG_MAC80211_LEDS=y
-# CONFIG_MAC80211_DEBUGFS is not set
-# CONFIG_MAC80211_DEBUG_MENU is not set
-CONFIG_WIMAX=m
-CONFIG_WIMAX_DEBUG_LEVEL=8
-CONFIG_RFKILL=m
-CONFIG_RFKILL_LEDS=y
-# CONFIG_RFKILL_INPUT is not set
-CONFIG_NET_9P=m
-CONFIG_NET_9P_VIRTIO=m
-CONFIG_NET_9P_RDMA=m
-# CONFIG_NET_9P_DEBUG is not set
-# CONFIG_CAIF is not set
-CONFIG_CEPH_LIB=m
-# CONFIG_CEPH_LIB_PRETTYDEBUG is not set
-# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set
-# CONFIG_NFC is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_DEVTMPFS is not set
-CONFIG_STANDALONE=y
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_FW_LOADER=m
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_DEBUG_DRIVER is not set
-CONFIG_DEBUG_DEVRES=y
-CONFIG_SYS_HYPERVISOR=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=m
-CONFIG_REGMAP_SPI=m
-CONFIG_CONNECTOR=m
-CONFIG_MTD=m
-CONFIG_MTD_TESTS=m
-CONFIG_MTD_REDBOOT_PARTS=m
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
-# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
-CONFIG_MTD_AR7_PARTS=m
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_HAVE_MTD_OTP=y
-CONFIG_MTD_BLKDEVS=m
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_BLOCK_RO=m
-CONFIG_FTL=m
-CONFIG_NFTL=m
-CONFIG_NFTL_RW=y
-CONFIG_INFTL=m
-CONFIG_RFD_FTL=m
-CONFIG_SSFDC=m
-CONFIG_SM_FTL=m
-CONFIG_MTD_OOPS=m
-CONFIG_MTD_SWAP=m
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=m
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=m
-CONFIG_MTD_CFI_AMDSTD=m
-CONFIG_MTD_CFI_STAA=m
-CONFIG_MTD_CFI_UTIL=m
-CONFIG_MTD_RAM=m
-CONFIG_MTD_ROM=m
-CONFIG_MTD_ABSENT=m
-
-#
-# Mapping drivers for chip access
-#
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=m
-# CONFIG_MTD_PHYSMAP_COMPAT is not set
-CONFIG_MTD_SC520CDP=m
-CONFIG_MTD_NETSC520=m
-CONFIG_MTD_TS5500=m
-CONFIG_MTD_SBC_GXX=m
-CONFIG_MTD_AMD76XROM=m
-CONFIG_MTD_ICHXROM=m
-CONFIG_MTD_ESB2ROM=m
-CONFIG_MTD_CK804XROM=m
-CONFIG_MTD_SCB2_FLASH=m
-CONFIG_MTD_NETtel=m
-CONFIG_MTD_L440GX=m
-CONFIG_MTD_PCI=m
-CONFIG_MTD_PCMCIA=m
-# CONFIG_MTD_PCMCIA_ANONYMOUS is not set
-# CONFIG_MTD_GPIO_ADDR is not set
-CONFIG_MTD_INTEL_VR_NOR=m
-CONFIG_MTD_PLATRAM=m
-# CONFIG_MTD_LATCH_ADDR is not set
-
-#
-# Self-contained MTD device drivers
-#
-CONFIG_MTD_PMC551=m
-CONFIG_MTD_PMC551_BUGFIX=y
-# CONFIG_MTD_PMC551_DEBUG is not set
-CONFIG_MTD_DATAFLASH=m
-# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
-# CONFIG_MTD_DATAFLASH_OTP is not set
-CONFIG_MTD_M25P80=m
-CONFIG_M25PXX_USE_FAST_READ=y
-# CONFIG_MTD_SST25L is not set
-CONFIG_MTD_SLRAM=m
-CONFIG_MTD_PHRAM=m
-CONFIG_MTD_MTDRAM=m
-CONFIG_MTDRAM_TOTAL_SIZE=4096
-CONFIG_MTDRAM_ERASE_SIZE=128
-CONFIG_MTD_BLOCK2MTD=m
-
-#
-# Disk-On-Chip Device Drivers
-#
-CONFIG_MTD_DOC2000=m
-CONFIG_MTD_DOC2001=m
-CONFIG_MTD_DOC2001PLUS=m
-# CONFIG_MTD_DOCG3 is not set
-CONFIG_MTD_DOCPROBE=m
-CONFIG_MTD_DOCECC=m
-CONFIG_MTD_DOCPROBE_ADVANCED=y
-CONFIG_MTD_DOCPROBE_ADDRESS=0x0000
-# CONFIG_MTD_DOCPROBE_HIGH is not set
-# CONFIG_MTD_DOCPROBE_55AA is not set
-CONFIG_MTD_NAND_ECC=m
-CONFIG_MTD_NAND_ECC_SMC=y
-CONFIG_MTD_NAND=m
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_NAND_ECC_BCH is not set
-CONFIG_MTD_SM_COMMON=m
-# CONFIG_MTD_NAND_MUSEUM_IDS is not set
-CONFIG_MTD_NAND_DENALI=m
-CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018
-CONFIG_MTD_NAND_IDS=m
-CONFIG_MTD_NAND_RICOH=m
-CONFIG_MTD_NAND_DISKONCHIP=m
-# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
-CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
-# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
-CONFIG_MTD_NAND_CAFE=m
-CONFIG_MTD_NAND_NANDSIM=m
-CONFIG_MTD_NAND_PLATFORM=m
-CONFIG_MTD_ALAUDA=m
-CONFIG_MTD_ONENAND=m
-# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
-# CONFIG_MTD_ONENAND_GENERIC is not set
-CONFIG_MTD_ONENAND_OTP=y
-CONFIG_MTD_ONENAND_2X_PROGRAM=y
-CONFIG_MTD_ONENAND_SIM=m
-
-#
-# LPDDR flash memory drivers
-#
-CONFIG_MTD_LPDDR=m
-CONFIG_MTD_QINFO_PROBE=m
-CONFIG_MTD_UBI=m
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MTD_UBI_BEB_RESERVE=1
-# CONFIG_MTD_UBI_GLUEBI is not set
-# CONFIG_MTD_UBI_DEBUG is not set
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_SERIAL=m
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_PC_PCMCIA=m
-# CONFIG_PARPORT_GSC is not set
-CONFIG_PARPORT_AX88796=m
-# CONFIG_PARPORT_1284 is not set
-CONFIG_PARPORT_NOT_PC=y
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG_MESSAGES is not set
-
-#
-# Protocols
-#
-CONFIG_PNPACPI=y
-CONFIG_BLK_DEV=y
-CONFIG_BLK_DEV_FD=m
-# CONFIG_PARIDE is not set
-CONFIG_BLK_CPQ_DA=m
-CONFIG_BLK_CPQ_CISS_DA=m
-CONFIG_CISS_SCSI_TAPE=y
-CONFIG_BLK_DEV_DAC960=m
-CONFIG_BLK_DEV_UMEM=m
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-# CONFIG_BLK_DEV_DRBD is not set
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_OSD=m
-CONFIG_BLK_DEV_SX8=m
-CONFIG_BLK_DEV_UB=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_XIP is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-CONFIG_XEN_BLKDEV_FRONTEND=y
-CONFIG_XEN_BLKDEV_BACKEND=m
-CONFIG_VIRTIO_BLK=m
-# CONFIG_BLK_DEV_HD is not set
-# CONFIG_BLK_DEV_RBD is not set
-CONFIG_SENSORS_LIS3LV02D=m
-CONFIG_MISC_DEVICES=y
-CONFIG_AD525X_DPOT=m
-CONFIG_AD525X_DPOT_I2C=m
-CONFIG_AD525X_DPOT_SPI=m
-CONFIG_IBM_ASM=m
-CONFIG_PHANTOM=m
-# CONFIG_INTEL_MID_PTI is not set
-CONFIG_SGI_IOC4=m
-CONFIG_TIFM_CORE=m
-CONFIG_TIFM_7XX1=m
-CONFIG_ICS932S401=m
-CONFIG_ENCLOSURE_SERVICES=m
-CONFIG_CS5535_MFGPT=m
-CONFIG_CS5535_MFGPT_DEFAULT_IRQ=7
-CONFIG_CS5535_CLOCK_EVENT_SRC=m
-CONFIG_HP_ILO=m
-CONFIG_APDS9802ALS=m
-CONFIG_ISL29003=m
-CONFIG_ISL29020=m
-CONFIG_SENSORS_TSL2550=m
-CONFIG_SENSORS_BH1780=m
-CONFIG_SENSORS_BH1770=m
-CONFIG_SENSORS_APDS990X=m
-CONFIG_HMC6352=m
-CONFIG_DS1682=m
-CONFIG_TI_DAC7512=m
-CONFIG_VMWARE_BALLOON=m
-CONFIG_BMP085=m
-CONFIG_PCH_PHUB=m
-# CONFIG_USB_SWITCH_FSA9480 is not set
-CONFIG_C2PORT=m
-CONFIG_C2PORT_DURAMAR_2150=m
-
-#
-# EEPROM support
-#
-CONFIG_EEPROM_AT24=m
-CONFIG_EEPROM_AT25=m
-CONFIG_EEPROM_LEGACY=m
-CONFIG_EEPROM_MAX6875=m
-CONFIG_EEPROM_93CX6=m
-CONFIG_EEPROM_93XX46=m
-CONFIG_CB710_CORE=m
-# CONFIG_CB710_DEBUG is not set
-CONFIG_CB710_DEBUG_ASSUMPTIONS=y
-CONFIG_IWMC3200TOP=m
-# CONFIG_IWMC3200TOP_DEBUG is not set
-# CONFIG_IWMC3200TOP_DEBUGFS is not set
-
-#
-# Texas Instruments shared transport line discipline
-#
-CONFIG_TI_ST=m
-CONFIG_SENSORS_LIS3_I2C=m
-
-#
-# Altera FPGA firmware download module
-#
-# CONFIG_ALTERA_STAPL is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI_MOD=m
-CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=m
-CONFIG_SCSI_DMA=y
-CONFIG_SCSI_TGT=m
-CONFIG_SCSI_NETLINK=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_ENCLOSURE=m
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_FC_ATTRS=m
-CONFIG_SCSI_FC_TGT_ATTRS=y
-CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_SCSI_SAS_ATTRS=m
-CONFIG_SCSI_SAS_LIBSAS=m
-CONFIG_SCSI_SAS_ATA=y
-CONFIG_SCSI_SAS_HOST_SMP=y
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
-CONFIG_SCSI_LOWLEVEL=y
-CONFIG_ISCSI_TCP=m
-CONFIG_ISCSI_BOOT_SYSFS=m
-CONFIG_SCSI_CXGB3_ISCSI=m
-CONFIG_SCSI_CXGB4_ISCSI=m
-CONFIG_SCSI_BNX2_ISCSI=m
-CONFIG_SCSI_BNX2X_FCOE=m
-CONFIG_BE2ISCSI=m
-CONFIG_BLK_DEV_3W_XXXX_RAID=m
-CONFIG_SCSI_HPSA=m
-CONFIG_SCSI_3W_9XXX=m
-CONFIG_SCSI_3W_SAS=m
-CONFIG_SCSI_ACARD=m
-CONFIG_SCSI_AACRAID=m
-CONFIG_SCSI_AIC7XXX=m
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
-CONFIG_AIC7XXX_DEBUG_ENABLE=y
-CONFIG_AIC7XXX_DEBUG_MASK=0
-CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
-CONFIG_SCSI_AIC7XXX_OLD=m
-CONFIG_SCSI_AIC79XX=m
-CONFIG_AIC79XX_CMDS_PER_DEVICE=32
-CONFIG_AIC79XX_RESET_DELAY_MS=15000
-# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
-CONFIG_AIC79XX_DEBUG_ENABLE=y
-CONFIG_AIC79XX_DEBUG_MASK=0
-CONFIG_AIC79XX_REG_PRETTY_PRINT=y
-CONFIG_SCSI_AIC94XX=m
-# CONFIG_AIC94XX_DEBUG is not set
-CONFIG_SCSI_MVSAS=m
-CONFIG_SCSI_MVSAS_DEBUG=y
-CONFIG_SCSI_MVSAS_TASKLET=y
-CONFIG_SCSI_MVUMI=m
-CONFIG_SCSI_DPT_I2O=m
-CONFIG_SCSI_ADVANSYS=m
-CONFIG_SCSI_ARCMSR=m
-CONFIG_MEGARAID_NEWGEN=y
-CONFIG_MEGARAID_MM=m
-CONFIG_MEGARAID_MAILBOX=m
-CONFIG_MEGARAID_LEGACY=m
-CONFIG_MEGARAID_SAS=m
-CONFIG_SCSI_MPT2SAS=m
-CONFIG_SCSI_MPT2SAS_MAX_SGE=128
-# CONFIG_SCSI_MPT2SAS_LOGGING is not set
-CONFIG_SCSI_HPTIOP=m
-CONFIG_SCSI_BUSLOGIC=m
-CONFIG_VMWARE_PVSCSI=m
-CONFIG_LIBFC=m
-CONFIG_LIBFCOE=m
-CONFIG_FCOE=m
-CONFIG_FCOE_FNIC=m
-CONFIG_SCSI_DMX3191D=m
-CONFIG_SCSI_EATA=m
-# CONFIG_SCSI_EATA_TAGGED_QUEUE is not set
-# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
-CONFIG_SCSI_EATA_MAX_TAGS=16
-CONFIG_SCSI_FUTURE_DOMAIN=m
-CONFIG_SCSI_GDTH=m
-CONFIG_SCSI_ISCI=m
-CONFIG_SCSI_IPS=m
-CONFIG_SCSI_INITIO=m
-CONFIG_SCSI_INIA100=m
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-CONFIG_SCSI_STEX=m
-CONFIG_SCSI_SYM53C8XX_2=m
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-CONFIG_SCSI_SYM53C8XX_MMIO=y
-CONFIG_SCSI_IPR=m
-CONFIG_SCSI_IPR_TRACE=y
-# CONFIG_SCSI_IPR_DUMP is not set
-CONFIG_SCSI_QLOGIC_1280=m
-CONFIG_SCSI_QLA_FC=m
-CONFIG_SCSI_QLA_ISCSI=m
-CONFIG_SCSI_LPFC=m
-# CONFIG_SCSI_LPFC_DEBUG_FS is not set
-CONFIG_SCSI_DC395x=m
-CONFIG_SCSI_DC390T=m
-CONFIG_SCSI_DEBUG=m
-# CONFIG_SCSI_PMCRAID is not set
-CONFIG_SCSI_PM8001=m
-CONFIG_SCSI_SRP=m
-# CONFIG_SCSI_BFA_FC is not set
-# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
-CONFIG_SCSI_DH=m
-CONFIG_SCSI_DH_RDAC=m
-CONFIG_SCSI_DH_HP_SW=m
-CONFIG_SCSI_DH_EMC=m
-CONFIG_SCSI_DH_ALUA=m
-CONFIG_SCSI_OSD_INITIATOR=m
-CONFIG_SCSI_OSD_ULD=m
-CONFIG_SCSI_OSD_DPRINT_SENSE=1
-# CONFIG_SCSI_OSD_DEBUG is not set
-
-#
-# SCSI target (SCST) support
-#
-CONFIG_SCST=m
-CONFIG_SCST_DISK=m
-CONFIG_SCST_TAPE=m
-CONFIG_SCST_CDROM=m
-CONFIG_SCST_MODISK=m
-CONFIG_SCST_CHANGER=m
-CONFIG_SCST_PROCESSOR=m
-CONFIG_SCST_RAID=m
-CONFIG_SCST_VDISK=m
-CONFIG_SCST_USER=m
-# CONFIG_SCST_STRICT_SERIALIZING is not set
-# CONFIG_SCST_STRICT_SECURITY is not set
-# CONFIG_SCST_TEST_IO_IN_SIRQ is not set
-# CONFIG_SCST_ABORT_CONSIDER_FINISHED_TASKS_AS_NOT_EXISTING is not set
-# CONFIG_SCST_USE_EXPECTED_VALUES is not set
-# CONFIG_SCST_EXTRACHECKS is not set
-CONFIG_SCST_TRACING=y
-# CONFIG_SCST_DEBUG is not set
-# CONFIG_SCST_DEBUG_OOM is not set
-# CONFIG_SCST_DEBUG_RETRY is not set
-# CONFIG_SCST_DEBUG_SN is not set
-# CONFIG_SCST_MEASURE_LATENCY is not set
-CONFIG_SCST_ISCSI=m
-# CONFIG_SCST_ISCSI_DEBUG_DIGEST_FAILURES is not set
-CONFIG_SCST_LOCAL=m
-# CONFIG_SCST_LOCAL_FORCE_DIRECT_PROCESSING is not set
-CONFIG_SCST_SRPT=m
-CONFIG_ATA=m
-# CONFIG_ATA_NONSTANDARD is not set
-CONFIG_ATA_VERBOSE_ERROR=y
-CONFIG_ATA_ACPI=y
-CONFIG_SATA_PMP=y
-
-#
-# Controllers with non-SFF native interface
-#
-CONFIG_SATA_AHCI=m
-CONFIG_SATA_AHCI_PLATFORM=m
-CONFIG_SATA_INIC162X=m
-CONFIG_SATA_ACARD_AHCI=m
-CONFIG_SATA_SIL24=m
-CONFIG_ATA_SFF=y
-
-#
-# SFF controllers with custom DMA interface
-#
-CONFIG_PDC_ADMA=m
-CONFIG_SATA_QSTOR=m
-CONFIG_SATA_SX4=m
-CONFIG_ATA_BMDMA=y
-
-#
-# SATA SFF controllers with BMDMA
-#
-CONFIG_ATA_PIIX=m
-CONFIG_SATA_MV=m
-CONFIG_SATA_NV=m
-CONFIG_SATA_PROMISE=m
-CONFIG_SATA_SIL=m
-CONFIG_SATA_SIS=m
-CONFIG_SATA_SVW=m
-CONFIG_SATA_ULI=m
-CONFIG_SATA_VIA=m
-CONFIG_SATA_VITESSE=m
-
-#
-# PATA SFF controllers with BMDMA
-#
-CONFIG_PATA_ALI=m
-CONFIG_PATA_AMD=m
-CONFIG_PATA_ARASAN_CF=m
-CONFIG_PATA_ARTOP=m
-CONFIG_PATA_ATIIXP=m
-CONFIG_PATA_ATP867X=m
-CONFIG_PATA_CMD64X=m
-CONFIG_PATA_CS5520=m
-CONFIG_PATA_CS5530=m
-CONFIG_PATA_CS5536=m
-CONFIG_PATA_CYPRESS=m
-CONFIG_PATA_EFAR=m
-CONFIG_PATA_HPT366=m
-CONFIG_PATA_HPT37X=m
-CONFIG_PATA_HPT3X2N=m
-CONFIG_PATA_HPT3X3=m
-CONFIG_PATA_HPT3X3_DMA=y
-CONFIG_PATA_IT8213=m
-CONFIG_PATA_IT821X=m
-CONFIG_PATA_JMICRON=m
-CONFIG_PATA_MARVELL=m
-CONFIG_PATA_NETCELL=m
-CONFIG_PATA_NINJA32=m
-CONFIG_PATA_NS87415=m
-CONFIG_PATA_OLDPIIX=m
-CONFIG_PATA_OPTIDMA=m
-CONFIG_PATA_PDC2027X=m
-CONFIG_PATA_PDC_OLD=m
-CONFIG_PATA_RADISYS=m
-CONFIG_PATA_RDC=m
-CONFIG_PATA_SC1200=m
-CONFIG_PATA_SCH=m
-CONFIG_PATA_SERVERWORKS=m
-CONFIG_PATA_SIL680=m
-CONFIG_PATA_SIS=m
-CONFIG_PATA_TOSHIBA=m
-CONFIG_PATA_TRIFLEX=m
-CONFIG_PATA_VIA=m
-CONFIG_PATA_WINBOND=m
-
-#
-# PIO-only SFF controllers
-#
-CONFIG_PATA_CMD640_PCI=m
-CONFIG_PATA_MPIIX=m
-CONFIG_PATA_NS87410=m
-CONFIG_PATA_OPTI=m
-CONFIG_PATA_PCMCIA=m
-CONFIG_PATA_PLATFORM=m
-CONFIG_PATA_RZ1000=m
-
-#
-# Generic fallback / legacy drivers
-#
-CONFIG_PATA_ACPI=m
-CONFIG_ATA_GENERIC=m
-CONFIG_PATA_LEGACY=m
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-# CONFIG_MD_AUTODETECT is not set
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID456=m
-# CONFIG_MULTICORE_RAID456 is not set
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-# CONFIG_DM_DEBUG is not set
-CONFIG_DM_BUFIO=m
-CONFIG_DM_PERSISTENT_DATA=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_THIN_PROVISIONING=m
-# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set
-# CONFIG_DM_DEBUG_SPACE_MAPS is not set
-CONFIG_DM_MIRROR=m
-CONFIG_DM_RAID=m
-CONFIG_DM_LOG_USERSPACE=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_QL=m
-CONFIG_DM_MULTIPATH_ST=m
-CONFIG_DM_DELAY=m
-# CONFIG_DM_UEVENT is not set
-CONFIG_DM_FLAKEY=m
-CONFIG_TARGET_CORE=m
-CONFIG_TCM_IBLOCK=m
-CONFIG_TCM_FILEIO=m
-CONFIG_TCM_PSCSI=m
-CONFIG_LOOPBACK_TARGET=m
-CONFIG_TCM_FC=m
-CONFIG_ISCSI_TARGET=m
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=m
-CONFIG_FUSION_FC=m
-CONFIG_FUSION_SAS=m
-CONFIG_FUSION_MAX_SGE=128
-CONFIG_FUSION_CTL=m
-# CONFIG_FUSION_LOGGING is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-CONFIG_FIREWIRE=m
-CONFIG_FIREWIRE_OHCI=m
-CONFIG_FIREWIRE_OHCI_DEBUG=y
-CONFIG_FIREWIRE_SBP2=m
-CONFIG_FIREWIRE_NET=m
-CONFIG_FIREWIRE_NOSY=m
-CONFIG_I2O=m
-CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
-CONFIG_I2O_EXT_ADAPTEC=y
-CONFIG_I2O_EXT_ADAPTEC_DMA64=y
-CONFIG_I2O_CONFIG=m
-CONFIG_I2O_CONFIG_OLD_IOCTL=y
-CONFIG_I2O_BUS=m
-CONFIG_I2O_BLOCK=m
-CONFIG_I2O_SCSI=m
-CONFIG_I2O_PROC=m
-# CONFIG_MACINTOSH_DRIVERS is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_CORE=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_EQUALIZER=m
-# CONFIG_NET_FC is not set
-CONFIG_MII=m
-CONFIG_IEEE802154_DRIVERS=m
-CONFIG_IEEE802154_FAKEHARD=m
-CONFIG_IFB=m
-CONFIG_MACVLAN=m
-CONFIG_MACVTAP=m
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-CONFIG_TUN=m
-CONFIG_VETH=m
-CONFIG_VIRTIO_NET=m
-CONFIG_SUNGEM_PHY=m
-CONFIG_ARCNET=m
-CONFIG_ARCNET_1201=m
-CONFIG_ARCNET_1051=m
-CONFIG_ARCNET_RAW=m
-CONFIG_ARCNET_CAP=m
-CONFIG_ARCNET_COM90xx=m
-CONFIG_ARCNET_COM90xxIO=m
-CONFIG_ARCNET_RIM_I=m
-CONFIG_ARCNET_COM20020=m
-CONFIG_ARCNET_COM20020_PCI=m
-CONFIG_ARCNET_COM20020_CS=m
-CONFIG_ATM_DRIVERS=y
-CONFIG_ATM_DUMMY=m
-CONFIG_ATM_TCP=m
-CONFIG_ATM_LANAI=m
-CONFIG_ATM_ENI=m
-# CONFIG_ATM_ENI_DEBUG is not set
-# CONFIG_ATM_ENI_TUNE_BURST is not set
-CONFIG_ATM_FIRESTREAM=m
-CONFIG_ATM_ZATM=m
-# CONFIG_ATM_ZATM_DEBUG is not set
-CONFIG_ATM_NICSTAR=m
-# CONFIG_ATM_NICSTAR_USE_SUNI is not set
-# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
-CONFIG_ATM_IDT77252=m
-# CONFIG_ATM_IDT77252_DEBUG is not set
-# CONFIG_ATM_IDT77252_RCV_ALL is not set
-CONFIG_ATM_IDT77252_USE_SUNI=y
-CONFIG_ATM_AMBASSADOR=m
-# CONFIG_ATM_AMBASSADOR_DEBUG is not set
-CONFIG_ATM_HORIZON=m
-# CONFIG_ATM_HORIZON_DEBUG is not set
-CONFIG_ATM_IA=m
-# CONFIG_ATM_IA_DEBUG is not set
-CONFIG_ATM_FORE200E=m
-CONFIG_ATM_FORE200E_USE_TASKLET=y
-CONFIG_ATM_FORE200E_TX_RETRY=16
-CONFIG_ATM_FORE200E_DEBUG=0
-CONFIG_ATM_HE=m
-CONFIG_ATM_HE_USE_SUNI=y
-CONFIG_ATM_SOLOS=m
-
-#
-# CAIF transport drivers
-#
-CONFIG_ETHERNET=y
-CONFIG_MDIO=m
-CONFIG_NET_VENDOR_3COM=y
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_3C589=m
-CONFIG_VORTEX=m
-CONFIG_TYPHOON=m
-CONFIG_NET_VENDOR_ADAPTEC=y
-CONFIG_ADAPTEC_STARFIRE=m
-CONFIG_NET_VENDOR_ALTEON=y
-CONFIG_ACENIC=m
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
-CONFIG_NET_VENDOR_AMD=y
-CONFIG_AMD8111_ETH=m
-CONFIG_PCNET32=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_NET_VENDOR_ATHEROS=y
-CONFIG_ATL2=m
-CONFIG_ATL1=m
-CONFIG_ATL1E=m
-CONFIG_ATL1C=m
-CONFIG_NET_VENDOR_BROADCOM=y
-CONFIG_B44=m
-CONFIG_B44_PCI_AUTOSELECT=y
-CONFIG_B44_PCICORE_AUTOSELECT=y
-CONFIG_B44_PCI=y
-CONFIG_BNX2=m
-CONFIG_CNIC=m
-CONFIG_TIGON3=m
-CONFIG_BNX2X=m
-CONFIG_NET_VENDOR_BROCADE=y
-CONFIG_BNA=m
-CONFIG_NET_VENDOR_CHELSIO=y
-CONFIG_CHELSIO_T1=m
-CONFIG_CHELSIO_T1_1G=y
-CONFIG_CHELSIO_T3=m
-CONFIG_CHELSIO_T4=m
-CONFIG_CHELSIO_T4VF=m
-CONFIG_NET_VENDOR_CISCO=y
-CONFIG_ENIC=m
-CONFIG_DNET=m
-CONFIG_NET_VENDOR_DEC=y
-CONFIG_NET_TULIP=y
-CONFIG_DE2104X=m
-CONFIG_DE2104X_DSL=0
-CONFIG_TULIP=m
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-# CONFIG_TULIP_NAPI is not set
-CONFIG_DE4X5=m
-CONFIG_WINBOND_840=m
-CONFIG_DM9102=m
-CONFIG_ULI526X=m
-CONFIG_PCMCIA_XIRCOM=m
-CONFIG_NET_VENDOR_DLINK=y
-CONFIG_DE600=m
-CONFIG_DE620=m
-CONFIG_DL2K=m
-CONFIG_SUNDANCE=m
-# CONFIG_SUNDANCE_MMIO is not set
-CONFIG_NET_VENDOR_EMULEX=y
-CONFIG_BE2NET=m
-CONFIG_NET_VENDOR_EXAR=y
-CONFIG_S2IO=m
-CONFIG_VXGE=m
-# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
-CONFIG_NET_VENDOR_FUJITSU=y
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_NET_VENDOR_HP=y
-CONFIG_HP100=m
-CONFIG_NET_VENDOR_INTEL=y
-CONFIG_E100=m
-CONFIG_E1000=m
-CONFIG_E1000E=m
-CONFIG_IGB=m
-CONFIG_IGB_DCA=y
-CONFIG_IGBVF=m
-CONFIG_IXGB=m
-CONFIG_IXGBE=m
-CONFIG_IXGBE_DCA=y
-# CONFIG_IXGBEVF is not set
-CONFIG_NET_VENDOR_I825XX=y
-# CONFIG_ZNET is not set
-CONFIG_IP1000=m
-CONFIG_JME=m
-CONFIG_NET_VENDOR_MARVELL=y
-CONFIG_SKGE=m
-# CONFIG_SKGE_DEBUG is not set
-CONFIG_SKGE_GENESIS=y
-CONFIG_SKY2=m
-# CONFIG_SKY2_DEBUG is not set
-CONFIG_NET_VENDOR_MELLANOX=y
-CONFIG_MLX4_EN=m
-CONFIG_MLX4_CORE=m
-CONFIG_MLX4_DEBUG=y
-CONFIG_NET_VENDOR_MICREL=y
-CONFIG_KS8842=m
-CONFIG_KS8851=m
-CONFIG_KS8851_MLL=m
-CONFIG_KSZ884X_PCI=m
-CONFIG_NET_VENDOR_MICROCHIP=y
-CONFIG_ENC28J60=m
-# CONFIG_ENC28J60_WRITEVERIFY is not set
-CONFIG_NET_VENDOR_MYRI=y
-CONFIG_MYRI10GE=m
-CONFIG_MYRI10GE_DCA=y
-CONFIG_FEALNX=m
-CONFIG_NET_VENDOR_NATSEMI=y
-CONFIG_NATSEMI=m
-CONFIG_NS83820=m
-CONFIG_NET_VENDOR_8390=y
-CONFIG_PCMCIA_AXNET=m
-CONFIG_NE2K_PCI=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_NET_VENDOR_NVIDIA=y
-CONFIG_FORCEDETH=m
-CONFIG_NET_VENDOR_OKI=y
-CONFIG_PCH_GBE=m
-CONFIG_ETHOC=m
-CONFIG_NET_PACKET_ENGINE=y
-CONFIG_HAMACHI=m
-CONFIG_YELLOWFIN=m
-CONFIG_NET_VENDOR_QLOGIC=y
-CONFIG_QLA3XXX=m
-CONFIG_QLCNIC=m
-CONFIG_QLGE=m
-CONFIG_NETXEN_NIC=m
-CONFIG_NET_VENDOR_REALTEK=y
-CONFIG_ATP=m
-CONFIG_8139CP=m
-CONFIG_8139TOO=m
-CONFIG_8139TOO_PIO=y
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-CONFIG_R8169=m
-CONFIG_NET_VENDOR_RDC=y
-CONFIG_R6040=m
-CONFIG_NET_VENDOR_SEEQ=y
-CONFIG_SEEQ8005=m
-CONFIG_NET_VENDOR_SILAN=y
-CONFIG_SC92031=m
-CONFIG_NET_VENDOR_SIS=y
-CONFIG_SIS900=m
-CONFIG_SIS190=m
-CONFIG_SFC=m
-CONFIG_SFC_MTD=y
-CONFIG_NET_VENDOR_SMSC=y
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_EPIC100=m
-CONFIG_SMSC9420=m
-CONFIG_NET_VENDOR_STMICRO=y
-CONFIG_STMMAC_ETH=m
-# CONFIG_STMMAC_DEBUG_FS is not set
-# CONFIG_STMMAC_DA is not set
-CONFIG_STMMAC_RING=y
-# CONFIG_STMMAC_CHAINED is not set
-CONFIG_NET_VENDOR_SUN=y
-CONFIG_HAPPYMEAL=m
-CONFIG_SUNGEM=m
-CONFIG_CASSINI=m
-CONFIG_NIU=m
-CONFIG_NET_VENDOR_TEHUTI=y
-CONFIG_TEHUTI=m
-CONFIG_NET_VENDOR_TI=y
-CONFIG_TLAN=m
-CONFIG_NET_VENDOR_VIA=y
-CONFIG_VIA_RHINE=m
-# CONFIG_VIA_RHINE_MMIO is not set
-CONFIG_VIA_VELOCITY=m
-CONFIG_NET_VENDOR_XIRCOM=y
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_FDDI=y
-CONFIG_DEFXX=m
-# CONFIG_DEFXX_MMIO is not set
-CONFIG_SKFP=m
-CONFIG_HIPPI=y
-CONFIG_ROADRUNNER=m
-# CONFIG_ROADRUNNER_LARGE_RINGS is not set
-CONFIG_NET_SB1000=m
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-CONFIG_BROADCOM_PHY=m
-CONFIG_ICPLUS_PHY=m
-CONFIG_REALTEK_PHY=m
-CONFIG_NATIONAL_PHY=m
-CONFIG_STE10XP=m
-CONFIG_LSI_ET1011C_PHY=m
-CONFIG_MICREL_PHY=m
-CONFIG_MDIO_BITBANG=m
-CONFIG_MDIO_GPIO=m
-CONFIG_PLIP=m
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_MPPE=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPPOATM=m
-CONFIG_PPPOE=m
-CONFIG_PPTP=m
-CONFIG_PPPOL2TP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_SLIP=m
-CONFIG_SLHC=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_TR is not set
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_AX8817X=m
-CONFIG_USB_NET_CDCETHER=m
-CONFIG_USB_NET_CDC_EEM=m
-CONFIG_USB_NET_CDC_NCM=m
-CONFIG_USB_NET_DM9601=m
-CONFIG_USB_NET_SMSC75XX=m
-CONFIG_USB_NET_SMSC95XX=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_NET1080=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_MCS7830=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_NET_CDC_SUBSET=m
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_USB_NET_ZAURUS=m
-CONFIG_USB_NET_CX82310_ETH=m
-CONFIG_USB_NET_KALMIA=m
-CONFIG_USB_HSO=m
-CONFIG_USB_NET_INT51X1=m
-CONFIG_USB_CDC_PHONET=m
-CONFIG_USB_IPHETH=m
-CONFIG_USB_SIERRA_NET=m
-CONFIG_USB_VL600=m
-CONFIG_WLAN=y
-CONFIG_PCMCIA_RAYCS=m
-CONFIG_LIBERTAS_THINFIRM=m
-# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set
-CONFIG_LIBERTAS_THINFIRM_USB=m
-CONFIG_AIRO=m
-CONFIG_ATMEL=m
-CONFIG_PCI_ATMEL=m
-CONFIG_PCMCIA_ATMEL=m
-CONFIG_AT76C50X_USB=m
-CONFIG_AIRO_CS=m
-CONFIG_PCMCIA_WL3501=m
-CONFIG_PRISM54=m
-CONFIG_USB_ZD1201=m
-CONFIG_USB_NET_RNDIS_WLAN=m
-CONFIG_RTL8180=m
-CONFIG_RTL8187=m
-CONFIG_RTL8187_LEDS=y
-CONFIG_ADM8211=m
-CONFIG_MAC80211_HWSIM=m
-CONFIG_MWL8K=m
-CONFIG_ATH_COMMON=m
-# CONFIG_ATH_DEBUG is not set
-CONFIG_ATH5K=m
-# CONFIG_ATH5K_DEBUG is not set
-CONFIG_ATH5K_PCI=y
-CONFIG_ATH9K_HW=m
-CONFIG_ATH9K_COMMON=m
-CONFIG_ATH9K=m
-CONFIG_ATH9K_PCI=y
-CONFIG_ATH9K_AHB=y
-# CONFIG_ATH9K_DEBUGFS is not set
-CONFIG_ATH9K_RATE_CONTROL=y
-CONFIG_ATH9K_HTC=m
-# CONFIG_ATH9K_HTC_DEBUGFS is not set
-CONFIG_CARL9170=m
-CONFIG_CARL9170_LEDS=y
-CONFIG_CARL9170_WPC=y
-CONFIG_CARL9170_HWRNG=y
-CONFIG_ATH6KL=m
-CONFIG_ATH6KL_DEBUG=y
-CONFIG_B43=m
-CONFIG_B43_SSB=y
-CONFIG_B43_PCI_AUTOSELECT=y
-CONFIG_B43_PCICORE_AUTOSELECT=y
-CONFIG_B43_PCMCIA=y
-CONFIG_B43_SDIO=y
-CONFIG_B43_PIO=y
-CONFIG_B43_PHY_N=y
-CONFIG_B43_PHY_LP=y
-CONFIG_B43_PHY_HT=y
-CONFIG_B43_LEDS=y
-CONFIG_B43_HWRNG=y
-# CONFIG_B43_DEBUG is not set
-CONFIG_B43LEGACY=m
-CONFIG_B43LEGACY_PCI_AUTOSELECT=y
-CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
-CONFIG_B43LEGACY_LEDS=y
-CONFIG_B43LEGACY_HWRNG=y
-CONFIG_B43LEGACY_DEBUG=y
-CONFIG_B43LEGACY_DMA=y
-CONFIG_B43LEGACY_PIO=y
-CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
-# CONFIG_B43LEGACY_DMA_MODE is not set
-# CONFIG_B43LEGACY_PIO_MODE is not set
-# CONFIG_BRCMSMAC is not set
-# CONFIG_BRCMFMAC is not set
-CONFIG_HOSTAP=m
-CONFIG_HOSTAP_FIRMWARE=y
-CONFIG_HOSTAP_FIRMWARE_NVRAM=y
-CONFIG_HOSTAP_PLX=m
-CONFIG_HOSTAP_PCI=m
-CONFIG_HOSTAP_CS=m
-CONFIG_IPW2100=m
-CONFIG_IPW2100_MONITOR=y
-# CONFIG_IPW2100_DEBUG is not set
-CONFIG_IPW2200=m
-CONFIG_IPW2200_MONITOR=y
-CONFIG_IPW2200_RADIOTAP=y
-CONFIG_IPW2200_PROMISCUOUS=y
-CONFIG_IPW2200_QOS=y
-# CONFIG_IPW2200_DEBUG is not set
-CONFIG_LIBIPW=m
-# CONFIG_LIBIPW_DEBUG is not set
-CONFIG_IWLWIFI=m
-
-#
-# Debugging Options
-#
-# CONFIG_IWLWIFI_DEBUG is not set
-# CONFIG_IWLWIFI_DEVICE_SVTOOL is not set
-CONFIG_IWLWIFI_LEGACY=m
-
-#
-# Debugging Options
-#
-# CONFIG_IWLWIFI_LEGACY_DEBUG is not set
-CONFIG_IWL4965=m
-CONFIG_IWL3945=m
-CONFIG_IWM=m
-# CONFIG_IWM_DEBUG is not set
-CONFIG_LIBERTAS=m
-CONFIG_LIBERTAS_USB=m
-CONFIG_LIBERTAS_CS=m
-CONFIG_LIBERTAS_SDIO=m
-CONFIG_LIBERTAS_SPI=m
-# CONFIG_LIBERTAS_DEBUG is not set
-CONFIG_LIBERTAS_MESH=y
-CONFIG_HERMES=m
-# CONFIG_HERMES_PRISM is not set
-CONFIG_HERMES_CACHE_FW_ON_INIT=y
-CONFIG_PLX_HERMES=m
-CONFIG_TMD_HERMES=m
-CONFIG_NORTEL_HERMES=m
-CONFIG_PCMCIA_HERMES=m
-CONFIG_PCMCIA_SPECTRUM=m
-CONFIG_ORINOCO_USB=m
-CONFIG_P54_COMMON=m
-CONFIG_P54_USB=m
-CONFIG_P54_PCI=m
-CONFIG_P54_SPI=m
-# CONFIG_P54_SPI_DEFAULT_EEPROM is not set
-CONFIG_P54_LEDS=y
-CONFIG_RT2X00=m
-CONFIG_RT2400PCI=m
-CONFIG_RT2500PCI=m
-CONFIG_RT61PCI=m
-CONFIG_RT2800PCI=m
-CONFIG_RT2800PCI_RT33XX=y
-# CONFIG_RT2800PCI_RT35XX is not set
-CONFIG_RT2800PCI_RT53XX=y
-CONFIG_RT2500USB=m
-CONFIG_RT73USB=m
-CONFIG_RT2800USB=m
-CONFIG_RT2800USB_RT33XX=y
-# CONFIG_RT2800USB_RT35XX is not set
-CONFIG_RT2800USB_RT53XX=y
-CONFIG_RT2800USB_UNKNOWN=y
-CONFIG_RT2800_LIB=m
-CONFIG_RT2X00_LIB_PCI=m
-CONFIG_RT2X00_LIB_USB=m
-CONFIG_RT2X00_LIB=m
-CONFIG_RT2X00_LIB_FIRMWARE=y
-CONFIG_RT2X00_LIB_CRYPTO=y
-CONFIG_RT2X00_LIB_LEDS=y
-# CONFIG_RT2X00_DEBUG is not set
-CONFIG_RTL8192CE=m
-CONFIG_RTL8192SE=m
-CONFIG_RTL8192DE=m
-CONFIG_RTL8192CU=m
-CONFIG_RTLWIFI=m
-CONFIG_RTL8192C_COMMON=m
-CONFIG_WL1251=m
-CONFIG_WL1251_SPI=m
-CONFIG_WL1251_SDIO=m
-CONFIG_WL12XX_MENU=m
-CONFIG_WL12XX=m
-CONFIG_WL12XX_SPI=m
-CONFIG_WL12XX_SDIO=m
-CONFIG_WL12XX_SDIO_TEST=m
-CONFIG_WL12XX_PLATFORM_DATA=y
-CONFIG_ZD1211RW=m
-# CONFIG_ZD1211RW_DEBUG is not set
-CONFIG_MWIFIEX=m
-CONFIG_MWIFIEX_SDIO=m
-CONFIG_MWIFIEX_PCIE=m
-
-#
-# WiMAX Wireless Broadband devices
-#
-CONFIG_WIMAX_I2400M=m
-CONFIG_WIMAX_I2400M_USB=m
-CONFIG_WIMAX_I2400M_SDIO=m
-CONFIG_WIMAX_IWMC3200_SDIO=y
-CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8
-CONFIG_WAN=y
-CONFIG_LANMEDIA=m
-CONFIG_HDLC=m
-CONFIG_HDLC_RAW=m
-CONFIG_HDLC_RAW_ETH=m
-CONFIG_HDLC_CISCO=m
-CONFIG_HDLC_FR=m
-CONFIG_HDLC_PPP=m
-CONFIG_HDLC_X25=m
-CONFIG_PCI200SYN=m
-CONFIG_WANXL=m
-# CONFIG_WANXL_BUILD_FIRMWARE is not set
-CONFIG_PC300TOO=m
-CONFIG_FARSYNC=m
-CONFIG_DSCC4=m
-CONFIG_DSCC4_PCISYNC=y
-CONFIG_DSCC4_PCI_RST=y
-CONFIG_DLCI=m
-CONFIG_DLCI_MAX=8
-CONFIG_WAN_ROUTER_DRIVERS=m
-CONFIG_CYCLADES_SYNC=m
-CONFIG_CYCLOMX_X25=y
-CONFIG_LAPBETHER=m
-CONFIG_X25_ASY=m
-CONFIG_SBNI=m
-CONFIG_SBNI_MULTILINE=y
-CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_BACKEND=m
-CONFIG_VMXNET3=m
-CONFIG_ISDN=y
-# CONFIG_ISDN_I4L is not set
-CONFIG_ISDN_CAPI=m
-# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
-# CONFIG_CAPI_TRACE is not set
-CONFIG_ISDN_CAPI_MIDDLEWARE=y
-CONFIG_ISDN_CAPI_CAPI20=m
-
-#
-# CAPI hardware drivers
-#
-CONFIG_CAPI_AVM=y
-CONFIG_ISDN_DRV_AVMB1_B1PCI=m
-CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
-CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
-CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
-CONFIG_ISDN_DRV_AVMB1_T1PCI=m
-CONFIG_ISDN_DRV_AVMB1_C4=m
-CONFIG_CAPI_EICON=y
-CONFIG_ISDN_DIVAS=m
-CONFIG_ISDN_DIVAS_BRIPCI=y
-CONFIG_ISDN_DIVAS_PRIPCI=y
-CONFIG_ISDN_DIVAS_DIVACAPI=m
-CONFIG_ISDN_DIVAS_USERIDI=m
-CONFIG_ISDN_DIVAS_MAINT=m
-CONFIG_ISDN_DRV_GIGASET=m
-CONFIG_GIGASET_CAPI=y
-# CONFIG_GIGASET_DUMMYLL is not set
-CONFIG_GIGASET_BASE=m
-CONFIG_GIGASET_M105=m
-CONFIG_GIGASET_M101=m
-# CONFIG_GIGASET_DEBUG is not set
-CONFIG_HYSDN=m
-CONFIG_HYSDN_CAPI=y
-CONFIG_MISDN=m
-CONFIG_MISDN_DSP=m
-CONFIG_MISDN_L1OIP=m
-
-#
-# mISDN hardware drivers
-#
-CONFIG_MISDN_HFCPCI=m
-CONFIG_MISDN_HFCMULTI=m
-CONFIG_MISDN_HFCUSB=m
-CONFIG_MISDN_AVMFRITZ=m
-# CONFIG_MISDN_SPEEDFAX is not set
-# CONFIG_MISDN_INFINEON is not set
-# CONFIG_MISDN_W6692 is not set
-# CONFIG_MISDN_NETJET is not set
-CONFIG_MISDN_IPAC=m
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-CONFIG_INPUT_FF_MEMLESS=m
-CONFIG_INPUT_POLLDEV=m
-CONFIG_INPUT_SPARSEKMAP=m
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ADP5588 is not set
-# CONFIG_KEYBOARD_ADP5589 is not set
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_QT1070 is not set
-# CONFIG_KEYBOARD_QT2160 is not set
-CONFIG_KEYBOARD_LKKBD=m
-CONFIG_KEYBOARD_GPIO=m
-CONFIG_KEYBOARD_GPIO_POLLED=m
-CONFIG_KEYBOARD_TCA6416=m
-CONFIG_KEYBOARD_MATRIX=m
-CONFIG_KEYBOARD_LM8323=m
-# CONFIG_KEYBOARD_MAX7359 is not set
-CONFIG_KEYBOARD_MCS=m
-# CONFIG_KEYBOARD_MPR121 is not set
-CONFIG_KEYBOARD_NEWTON=m
-# CONFIG_KEYBOARD_OPENCORES is not set
-CONFIG_KEYBOARD_STOWAWAY=m
-CONFIG_KEYBOARD_SUNKBD=m
-CONFIG_KEYBOARD_XTKBD=m
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=m
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_LIFEBOOK=y
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-# CONFIG_MOUSE_PS2_SENTELIC is not set
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-CONFIG_MOUSE_SERIAL=m
-CONFIG_MOUSE_APPLETOUCH=m
-CONFIG_MOUSE_BCM5974=m
-CONFIG_MOUSE_VSXXXAA=m
-CONFIG_MOUSE_GPIO=m
-CONFIG_MOUSE_SYNAPTICS_I2C=m
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=m
-CONFIG_TOUCHSCREEN_AD7877=m
-CONFIG_TOUCHSCREEN_AD7879=m
-CONFIG_TOUCHSCREEN_AD7879_I2C=m
-CONFIG_TOUCHSCREEN_AD7879_SPI=m
-CONFIG_TOUCHSCREEN_ATMEL_MXT=m
-CONFIG_TOUCHSCREEN_BU21013=m
-CONFIG_TOUCHSCREEN_CY8CTMG110=m
-CONFIG_TOUCHSCREEN_DYNAPRO=m
-CONFIG_TOUCHSCREEN_HAMPSHIRE=m
-CONFIG_TOUCHSCREEN_EETI=m
-CONFIG_TOUCHSCREEN_FUJITSU=m
-CONFIG_TOUCHSCREEN_GUNZE=m
-CONFIG_TOUCHSCREEN_ELO=m
-CONFIG_TOUCHSCREEN_WACOM_W8001=m
-# CONFIG_TOUCHSCREEN_MAX11801 is not set
-# CONFIG_TOUCHSCREEN_MCS5000 is not set
-CONFIG_TOUCHSCREEN_MTOUCH=m
-CONFIG_TOUCHSCREEN_INEXIO=m
-CONFIG_TOUCHSCREEN_MK712=m
-CONFIG_TOUCHSCREEN_PENMOUNT=m
-CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
-CONFIG_TOUCHSCREEN_TOUCHWIN=m
-CONFIG_TOUCHSCREEN_UCB1400=m
-CONFIG_TOUCHSCREEN_WM97XX=m
-CONFIG_TOUCHSCREEN_WM9705=y
-CONFIG_TOUCHSCREEN_WM9712=y
-CONFIG_TOUCHSCREEN_WM9713=y
-CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
-# CONFIG_TOUCHSCREEN_MC13783 is not set
-CONFIG_TOUCHSCREEN_USB_EGALAX=y
-CONFIG_TOUCHSCREEN_USB_PANJIT=y
-CONFIG_TOUCHSCREEN_USB_3M=y
-CONFIG_TOUCHSCREEN_USB_ITM=y
-CONFIG_TOUCHSCREEN_USB_ETURBO=y
-CONFIG_TOUCHSCREEN_USB_GUNZE=y
-CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
-CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
-CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
-CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
-CONFIG_TOUCHSCREEN_USB_GOTOP=y
-CONFIG_TOUCHSCREEN_USB_JASTEC=y
-CONFIG_TOUCHSCREEN_USB_E2I=y
-CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y
-CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y
-CONFIG_TOUCHSCREEN_USB_NEXIO=y
-CONFIG_TOUCHSCREEN_TOUCHIT213=m
-CONFIG_TOUCHSCREEN_TSC_SERIO=m
-# CONFIG_TOUCHSCREEN_TSC2005 is not set
-CONFIG_TOUCHSCREEN_TSC2007=m
-CONFIG_TOUCHSCREEN_ST1232=m
-CONFIG_TOUCHSCREEN_TPS6507X=m
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_AD714X=m
-CONFIG_INPUT_AD714X_I2C=m
-CONFIG_INPUT_AD714X_SPI=m
-# CONFIG_INPUT_BMA150 is not set
-CONFIG_INPUT_PCSPKR=m
-# CONFIG_INPUT_MC13783_PWRBUTTON is not set
-CONFIG_INPUT_MMA8450=m
-CONFIG_INPUT_MPU3050=m
-CONFIG_INPUT_APANEL=m
-CONFIG_INPUT_ATLAS_BTNS=m
-CONFIG_INPUT_ATI_REMOTE2=m
-CONFIG_INPUT_KEYSPAN_REMOTE=m
-CONFIG_INPUT_KXTJ9=m
-# CONFIG_INPUT_KXTJ9_POLLED_MODE is not set
-CONFIG_INPUT_POWERMATE=m
-CONFIG_INPUT_YEALINK=m
-CONFIG_INPUT_CM109=m
-CONFIG_INPUT_UINPUT=m
-CONFIG_INPUT_PCF50633_PMU=m
-CONFIG_INPUT_PCF8574=m
-CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
-CONFIG_INPUT_ADXL34X=m
-CONFIG_INPUT_ADXL34X_I2C=m
-CONFIG_INPUT_ADXL34X_SPI=m
-CONFIG_INPUT_CMA3000=m
-CONFIG_INPUT_CMA3000_I2C=m
-CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=m
-CONFIG_SERIO_CT82C710=m
-CONFIG_SERIO_PARKBD=m
-CONFIG_SERIO_PCIPS2=m
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=m
-CONFIG_SERIO_ALTERA_PS2=m
-CONFIG_SERIO_PS2MULT=m
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_CONSOLE_SLEEP=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_ROCKETPORT=m
-CONFIG_CYCLADES=m
-# CONFIG_CYZ_INTR is not set
-CONFIG_MOXA_INTELLIO=m
-CONFIG_MOXA_SMARTIO=m
-CONFIG_SYNCLINK=m
-CONFIG_SYNCLINKMP=m
-CONFIG_SYNCLINK_GT=m
-CONFIG_NOZOMI=m
-CONFIG_ISI=m
-CONFIG_N_HDLC=m
-# CONFIG_N_GSM is not set
-# CONFIG_TRACE_SINK is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_STALDRV=y
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_PNP=y
-CONFIG_SERIAL_8250_CS=m
-CONFIG_SERIAL_8250_NR_UARTS=16
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-CONFIG_SERIAL_8250_RSA=y
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_MAX3100=m
-CONFIG_SERIAL_MAX3107=m
-CONFIG_SERIAL_MRST_MAX3110=m
-CONFIG_SERIAL_MFD_HSU=m
-CONFIG_SERIAL_UARTLITE=m
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_JSM=m
-CONFIG_SERIAL_TIMBERDALE=m
-CONFIG_SERIAL_ALTERA_JTAGUART=m
-CONFIG_SERIAL_ALTERA_UART=m
-CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4
-CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200
-CONFIG_SERIAL_IFX6X60=m
-CONFIG_SERIAL_PCH_UART=m
-# CONFIG_SERIAL_XILINX_PS_UART is not set
-# CONFIG_TTY_PRINTK is not set
-CONFIG_PRINTER=m
-# CONFIG_LP_CONSOLE is not set
-CONFIG_PPDEV=m
-CONFIG_HVC_DRIVER=y
-CONFIG_HVC_IRQ=y
-CONFIG_HVC_XEN=y
-CONFIG_VIRTIO_CONSOLE=m
-CONFIG_IPMI_HANDLER=m
-# CONFIG_IPMI_PANIC_EVENT is not set
-CONFIG_IPMI_DEVICE_INTERFACE=m
-CONFIG_IPMI_SI=m
-CONFIG_IPMI_WATCHDOG=m
-CONFIG_IPMI_POWEROFF=m
-CONFIG_HW_RANDOM=m
-CONFIG_HW_RANDOM_TIMERIOMEM=m
-CONFIG_HW_RANDOM_INTEL=m
-CONFIG_HW_RANDOM_AMD=m
-CONFIG_HW_RANDOM_VIA=m
-CONFIG_HW_RANDOM_VIRTIO=m
-CONFIG_NVRAM=m
-CONFIG_R3964=m
-CONFIG_APPLICOM=m
-
-#
-# PCMCIA character devices
-#
-CONFIG_SYNCLINK_CS=m
-CONFIG_CARDMAN_4000=m
-CONFIG_CARDMAN_4040=m
-CONFIG_IPWIRELESS=m
-CONFIG_MWAVE=m
-CONFIG_RAW_DRIVER=m
-CONFIG_MAX_RAW_DEVS=256
-CONFIG_HPET=y
-CONFIG_HPET_MMAP=y
-CONFIG_HANGCHECK_TIMER=m
-CONFIG_TCG_TPM=m
-CONFIG_TCG_TIS=m
-CONFIG_TCG_NSC=m
-CONFIG_TCG_ATMEL=m
-CONFIG_TCG_INFINEON=m
-CONFIG_TELCLOCK=m
-CONFIG_DEVPORT=y
-CONFIG_RAMOOPS=m
-CONFIG_I2C=m
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_MUX=m
-
-#
-# Multiplexer I2C Chip support
-#
-CONFIG_I2C_MUX_GPIO=m
-CONFIG_I2C_MUX_PCA9541=m
-CONFIG_I2C_MUX_PCA954x=m
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_SMBUS=m
-CONFIG_I2C_ALGOBIT=m
-CONFIG_I2C_ALGOPCA=m
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# PC SMBus host controller drivers
-#
-CONFIG_I2C_ALI1535=m
-CONFIG_I2C_ALI1563=m
-CONFIG_I2C_ALI15X3=m
-CONFIG_I2C_AMD756=m
-CONFIG_I2C_AMD756_S4882=m
-CONFIG_I2C_AMD8111=m
-CONFIG_I2C_I801=m
-CONFIG_I2C_ISCH=m
-CONFIG_I2C_PIIX4=m
-CONFIG_I2C_NFORCE2=m
-CONFIG_I2C_NFORCE2_S4985=m
-CONFIG_I2C_SIS5595=m
-CONFIG_I2C_SIS630=m
-CONFIG_I2C_SIS96X=m
-CONFIG_I2C_VIA=m
-CONFIG_I2C_VIAPRO=m
-
-#
-# ACPI drivers
-#
-CONFIG_I2C_SCMI=m
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-# CONFIG_I2C_DESIGNWARE_PCI is not set
-CONFIG_I2C_GPIO=m
-CONFIG_I2C_INTEL_MID=m
-CONFIG_I2C_OCORES=m
-CONFIG_I2C_PCA_PLATFORM=m
-# CONFIG_I2C_PXA_PCI is not set
-CONFIG_I2C_SIMTEC=m
-CONFIG_I2C_XILINX=m
-CONFIG_I2C_EG20T=m
-
-#
-# External I2C/SMBus adapter drivers
-#
-CONFIG_I2C_DIOLAN_U2C=m
-CONFIG_I2C_PARPORT=m
-CONFIG_I2C_PARPORT_LIGHT=m
-CONFIG_I2C_TAOS_EVM=m
-CONFIG_I2C_TINY_USB=m
-
-#
-# Other I2C/SMBus bus drivers
-#
-CONFIG_I2C_STUB=m
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-CONFIG_SPI=y
-# CONFIG_SPI_DEBUG is not set
-CONFIG_SPI_MASTER=y
-
-#
-# SPI Master Controller Drivers
-#
-# CONFIG_SPI_ALTERA is not set
-CONFIG_SPI_BITBANG=m
-CONFIG_SPI_BUTTERFLY=m
-CONFIG_SPI_GPIO=m
-CONFIG_SPI_LM70_LLP=m
-# CONFIG_SPI_OC_TINY is not set
-# CONFIG_SPI_PXA2XX_PCI is not set
-CONFIG_SPI_TOPCLIFF_PCH=m
-# CONFIG_SPI_XILINX is not set
-CONFIG_SPI_DESIGNWARE=m
-CONFIG_SPI_DW_PCI=m
-
-#
-# SPI Protocol Masters
-#
-CONFIG_SPI_SPIDEV=m
-CONFIG_SPI_TLE62X0=m
-
-#
-# PPS support
-#
-# CONFIG_PPS is not set
-
-#
-# PPS generators support
-#
-
-#
-# PTP clock support
-#
-
-#
-# Enable Device Drivers -> PPS to see the PTP clock options.
-#
-CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
-CONFIG_GPIO_MAX730X=m
-
-#
-# Memory mapped GPIO drivers:
-#
-# CONFIG_GPIO_GENERIC_PLATFORM is not set
-CONFIG_GPIO_IT8761E=m
-CONFIG_GPIO_SCH=m
-CONFIG_GPIO_VX855=m
-
-#
-# I2C GPIO expanders:
-#
-CONFIG_GPIO_MAX7300=m
-CONFIG_GPIO_MAX732X=m
-CONFIG_GPIO_PCA953X=m
-CONFIG_GPIO_PCF857X=m
-CONFIG_GPIO_ADP5588=m
-
-#
-# PCI GPIO expanders:
-#
-CONFIG_GPIO_CS5535=m
-# CONFIG_GPIO_LANGWELL is not set
-CONFIG_GPIO_PCH=m
-CONFIG_GPIO_ML_IOH=m
-CONFIG_GPIO_TIMBERDALE=y
-CONFIG_GPIO_RDC321X=m
-
-#
-# SPI GPIO expanders:
-#
-CONFIG_GPIO_MAX7301=m
-CONFIG_GPIO_MCP23S08=m
-# CONFIG_GPIO_MC33880 is not set
-CONFIG_GPIO_74X164=m
-
-#
-# AC97 GPIO expanders:
-#
-# CONFIG_GPIO_UCB1400 is not set
-
-#
-# MODULbus GPIO expanders:
-#
-CONFIG_GPIO_JANZ_TTL=m
-# CONFIG_W1 is not set
-CONFIG_POWER_SUPPLY=m
-# CONFIG_POWER_SUPPLY_DEBUG is not set
-# CONFIG_PDA_POWER is not set
-# CONFIG_TEST_POWER is not set
-# CONFIG_BATTERY_DS2780 is not set
-# CONFIG_BATTERY_DS2782 is not set
-# CONFIG_BATTERY_BQ20Z75 is not set
-# CONFIG_BATTERY_BQ27x00 is not set
-# CONFIG_BATTERY_MAX17040 is not set
-# CONFIG_BATTERY_MAX17042 is not set
-# CONFIG_CHARGER_PCF50633 is not set
-# CONFIG_CHARGER_ISP1704 is not set
-# CONFIG_CHARGER_MAX8903 is not set
-# CONFIG_CHARGER_GPIO is not set
-CONFIG_HWMON=m
-CONFIG_HWMON_VID=m
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Native drivers
-#
-CONFIG_SENSORS_ABITUGURU=m
-CONFIG_SENSORS_ABITUGURU3=m
-CONFIG_SENSORS_AD7314=m
-CONFIG_SENSORS_AD7414=m
-CONFIG_SENSORS_AD7418=m
-CONFIG_SENSORS_ADCXX=m
-CONFIG_SENSORS_ADM1021=m
-CONFIG_SENSORS_ADM1025=m
-CONFIG_SENSORS_ADM1026=m
-CONFIG_SENSORS_ADM1029=m
-CONFIG_SENSORS_ADM1031=m
-CONFIG_SENSORS_ADM9240=m
-CONFIG_SENSORS_ADT7411=m
-CONFIG_SENSORS_ADT7462=m
-CONFIG_SENSORS_ADT7470=m
-CONFIG_SENSORS_ADT7475=m
-CONFIG_SENSORS_ASC7621=m
-CONFIG_SENSORS_K8TEMP=m
-CONFIG_SENSORS_K10TEMP=m
-CONFIG_SENSORS_FAM15H_POWER=m
-CONFIG_SENSORS_ASB100=m
-CONFIG_SENSORS_ATXP1=m
-CONFIG_SENSORS_DS620=m
-CONFIG_SENSORS_DS1621=m
-CONFIG_SENSORS_I5K_AMB=m
-CONFIG_SENSORS_F71805F=m
-CONFIG_SENSORS_F71882FG=m
-CONFIG_SENSORS_F75375S=m
-CONFIG_SENSORS_FSCHMD=m
-CONFIG_SENSORS_G760A=m
-CONFIG_SENSORS_GL518SM=m
-CONFIG_SENSORS_GL520SM=m
-CONFIG_SENSORS_GPIO_FAN=m
-CONFIG_SENSORS_CORETEMP=m
-CONFIG_SENSORS_IBMAEM=m
-CONFIG_SENSORS_IBMPEX=m
-CONFIG_SENSORS_IT87=m
-CONFIG_SENSORS_JC42=m
-CONFIG_SENSORS_LINEAGE=m
-CONFIG_SENSORS_LM63=m
-CONFIG_SENSORS_LM70=m
-CONFIG_SENSORS_LM73=m
-CONFIG_SENSORS_LM75=m
-CONFIG_SENSORS_LM77=m
-CONFIG_SENSORS_LM78=m
-CONFIG_SENSORS_LM80=m
-CONFIG_SENSORS_LM83=m
-CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_LM87=m
-CONFIG_SENSORS_LM90=m
-CONFIG_SENSORS_LM92=m
-CONFIG_SENSORS_LM93=m
-CONFIG_SENSORS_LTC4151=m
-CONFIG_SENSORS_LTC4215=m
-CONFIG_SENSORS_LTC4245=m
-CONFIG_SENSORS_LTC4261=m
-CONFIG_SENSORS_LM95241=m
-CONFIG_SENSORS_LM95245=m
-CONFIG_SENSORS_MAX1111=m
-CONFIG_SENSORS_MAX16065=m
-CONFIG_SENSORS_MAX1619=m
-CONFIG_SENSORS_MAX1668=m
-CONFIG_SENSORS_MAX6639=m
-CONFIG_SENSORS_MAX6642=m
-CONFIG_SENSORS_MAX6650=m
-CONFIG_SENSORS_NTC_THERMISTOR=m
-CONFIG_SENSORS_PC87360=m
-CONFIG_SENSORS_PC87427=m
-CONFIG_SENSORS_PCF8591=m
-CONFIG_PMBUS=m
-CONFIG_SENSORS_PMBUS=m
-CONFIG_SENSORS_ADM1275=m
-CONFIG_SENSORS_LM25066=m
-CONFIG_SENSORS_LTC2978=m
-CONFIG_SENSORS_MAX16064=m
-CONFIG_SENSORS_MAX34440=m
-CONFIG_SENSORS_MAX8688=m
-CONFIG_SENSORS_UCD9000=m
-CONFIG_SENSORS_UCD9200=m
-CONFIG_SENSORS_ZL6100=m
-CONFIG_SENSORS_SHT15=m
-CONFIG_SENSORS_SHT21=m
-CONFIG_SENSORS_SIS5595=m
-CONFIG_SENSORS_SMM665=m
-CONFIG_SENSORS_DME1737=m
-CONFIG_SENSORS_EMC1403=m
-CONFIG_SENSORS_EMC2103=m
-CONFIG_SENSORS_EMC6W201=m
-CONFIG_SENSORS_SMSC47M1=m
-CONFIG_SENSORS_SMSC47M192=m
-CONFIG_SENSORS_SMSC47B397=m
-CONFIG_SENSORS_SCH56XX_COMMON=m
-CONFIG_SENSORS_SCH5627=m
-CONFIG_SENSORS_SCH5636=m
-CONFIG_SENSORS_ADS1015=m
-CONFIG_SENSORS_ADS7828=m
-CONFIG_SENSORS_ADS7871=m
-CONFIG_SENSORS_AMC6821=m
-CONFIG_SENSORS_THMC50=m
-CONFIG_SENSORS_TMP102=m
-CONFIG_SENSORS_TMP401=m
-CONFIG_SENSORS_TMP421=m
-CONFIG_SENSORS_VIA_CPUTEMP=m
-CONFIG_SENSORS_VIA686A=m
-CONFIG_SENSORS_VT1211=m
-CONFIG_SENSORS_VT8231=m
-CONFIG_SENSORS_W83781D=m
-CONFIG_SENSORS_W83791D=m
-CONFIG_SENSORS_W83792D=m
-CONFIG_SENSORS_W83793=m
-CONFIG_SENSORS_W83795=m
-CONFIG_SENSORS_W83795_FANCTRL=y
-CONFIG_SENSORS_W83L785TS=m
-CONFIG_SENSORS_W83L786NG=m
-CONFIG_SENSORS_W83627HF=m
-CONFIG_SENSORS_W83627EHF=m
-CONFIG_SENSORS_APPLESMC=m
-# CONFIG_SENSORS_MC13783_ADC is not set
-
-#
-# ACPI drivers
-#
-CONFIG_SENSORS_ACPI_POWER=m
-CONFIG_SENSORS_ATK0110=m
-CONFIG_THERMAL=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-CONFIG_SOFT_WATCHDOG=m
-CONFIG_ACQUIRE_WDT=m
-CONFIG_ADVANTECH_WDT=m
-CONFIG_ALIM1535_WDT=m
-CONFIG_ALIM7101_WDT=m
-CONFIG_F71808E_WDT=m
-CONFIG_SP5100_TCO=m
-CONFIG_GEODE_WDT=m
-CONFIG_SC520_WDT=m
-# CONFIG_SBC_FITPC2_WATCHDOG is not set
-CONFIG_EUROTECH_WDT=m
-CONFIG_IB700_WDT=m
-CONFIG_IBMASR=m
-CONFIG_WAFER_WDT=m
-CONFIG_I6300ESB_WDT=m
-CONFIG_ITCO_WDT=m
-CONFIG_ITCO_VENDOR_SUPPORT=y
-CONFIG_IT8712F_WDT=m
-CONFIG_IT87_WDT=m
-# CONFIG_HP_WATCHDOG is not set
-CONFIG_SC1200_WDT=m
-CONFIG_PC87413_WDT=m
-CONFIG_NV_TCO=m
-CONFIG_60XX_WDT=m
-CONFIG_SBC8360_WDT=m
-CONFIG_CPU5_WDT=m
-CONFIG_SMSC_SCH311X_WDT=m
-CONFIG_SMSC37B787_WDT=m
-CONFIG_W83627HF_WDT=m
-CONFIG_W83697HF_WDT=m
-CONFIG_W83697UG_WDT=m
-CONFIG_W83877F_WDT=m
-CONFIG_W83977F_WDT=m
-CONFIG_MACHZ_WDT=m
-CONFIG_SBC_EPX_C3_WATCHDOG=m
-CONFIG_XEN_WDT=m
-
-#
-# PCI-based Watchdog Cards
-#
-CONFIG_PCIPCWATCHDOG=m
-CONFIG_WDTPCI=m
-
-#
-# USB-based Watchdog Cards
-#
-CONFIG_USBPCWATCHDOG=m
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB=m
-CONFIG_SSB_SPROM=y
-CONFIG_SSB_BLOCKIO=y
-CONFIG_SSB_PCIHOST_POSSIBLE=y
-CONFIG_SSB_PCIHOST=y
-CONFIG_SSB_B43_PCI_BRIDGE=y
-CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
-CONFIG_SSB_PCMCIAHOST=y
-CONFIG_SSB_SDIOHOST_POSSIBLE=y
-CONFIG_SSB_SDIOHOST=y
-# CONFIG_SSB_SILENT is not set
-# CONFIG_SSB_DEBUG is not set
-CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
-CONFIG_SSB_DRIVER_PCICORE=y
-CONFIG_BCMA_POSSIBLE=y
-
-#
-# Broadcom specific AMBA
-#
-# CONFIG_BCMA is not set
-
-#
-# Multifunction device drivers
-#
-CONFIG_MFD_CORE=m
-CONFIG_MFD_SM501=m
-# CONFIG_MFD_SM501_GPIO is not set
-CONFIG_HTC_PASIC3=m
-CONFIG_UCB1400_CORE=m
-# CONFIG_TPS6105X is not set
-CONFIG_TPS65010=m
-CONFIG_TPS6507X=m
-# CONFIG_MFD_TPS65912_SPI is not set
-# CONFIG_MFD_TMIO is not set
-CONFIG_MFD_WM8400=m
-# CONFIG_MFD_WM831X_SPI is not set
-CONFIG_MFD_PCF50633=m
-CONFIG_PCF50633_ADC=m
-CONFIG_PCF50633_GPIO=m
-CONFIG_MFD_MC13783=m
-CONFIG_MFD_MC13XXX=m
-CONFIG_ABX500_CORE=y
-# CONFIG_EZX_PCAP is not set
-# CONFIG_AB8500_CORE is not set
-CONFIG_MFD_CS5535=m
-CONFIG_MFD_TIMBERDALE=m
-CONFIG_LPC_SCH=m
-CONFIG_MFD_RDC321X=m
-CONFIG_MFD_JANZ_CMODIO=m
-CONFIG_MFD_VX855=m
-CONFIG_MFD_WL1273_CORE=m
-# CONFIG_REGULATOR is not set
-CONFIG_MEDIA_SUPPORT=m
-
-#
-# Multimedia core support
-#
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_DEV=m
-CONFIG_VIDEO_V4L2_COMMON=m
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
-CONFIG_DVB_CORE=m
-CONFIG_DVB_NET=y
-CONFIG_VIDEO_MEDIA=m
-
-#
-# Multimedia drivers
-#
-CONFIG_VIDEO_SAA7146=m
-CONFIG_VIDEO_SAA7146_VV=m
-CONFIG_RC_CORE=m
-CONFIG_LIRC=m
-CONFIG_RC_MAP=m
-CONFIG_IR_NEC_DECODER=m
-CONFIG_IR_RC5_DECODER=m
-CONFIG_IR_RC6_DECODER=m
-CONFIG_IR_JVC_DECODER=m
-CONFIG_IR_SONY_DECODER=m
-CONFIG_IR_RC5_SZ_DECODER=m
-CONFIG_IR_MCE_KBD_DECODER=m
-CONFIG_IR_LIRC_CODEC=m
-CONFIG_RC_ATI_REMOTE=m
-# CONFIG_IR_ENE is not set
-CONFIG_IR_IMON=m
-# CONFIG_IR_MCEUSB is not set
-CONFIG_IR_ITE_CIR=m
-CONFIG_IR_FINTEK=m
-# CONFIG_IR_NUVOTON is not set
-CONFIG_IR_REDRAT3=m
-# CONFIG_IR_STREAMZAP is not set
-CONFIG_IR_WINBOND_CIR=m
-CONFIG_RC_LOOPBACK=m
-# CONFIG_MEDIA_ATTACH is not set
-CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_MEDIA_TUNER_SIMPLE=m
-CONFIG_MEDIA_TUNER_TDA8290=m
-CONFIG_MEDIA_TUNER_TDA827X=m
-CONFIG_MEDIA_TUNER_TDA18271=m
-CONFIG_MEDIA_TUNER_TDA9887=m
-CONFIG_MEDIA_TUNER_TEA5761=m
-CONFIG_MEDIA_TUNER_TEA5767=m
-CONFIG_MEDIA_TUNER_MT20XX=m
-CONFIG_MEDIA_TUNER_MT2060=m
-CONFIG_MEDIA_TUNER_MT2266=m
-CONFIG_MEDIA_TUNER_MT2131=m
-CONFIG_MEDIA_TUNER_QT1010=m
-CONFIG_MEDIA_TUNER_XC2028=m
-CONFIG_MEDIA_TUNER_XC5000=m
-CONFIG_MEDIA_TUNER_XC4000=m
-CONFIG_MEDIA_TUNER_MXL5005S=m
-CONFIG_MEDIA_TUNER_MXL5007T=m
-CONFIG_MEDIA_TUNER_MC44S803=m
-CONFIG_MEDIA_TUNER_MAX2165=m
-CONFIG_MEDIA_TUNER_TDA18218=m
-CONFIG_MEDIA_TUNER_TDA18212=m
-CONFIG_VIDEO_V4L2=m
-CONFIG_VIDEOBUF_GEN=m
-CONFIG_VIDEOBUF_DMA_SG=m
-CONFIG_VIDEOBUF_VMALLOC=m
-CONFIG_VIDEOBUF_DMA_CONTIG=m
-CONFIG_VIDEOBUF_DVB=m
-CONFIG_VIDEO_BTCX=m
-CONFIG_VIDEO_TVEEPROM=m
-CONFIG_VIDEO_TUNER=m
-CONFIG_V4L2_MEM2MEM_DEV=m
-CONFIG_VIDEOBUF2_CORE=m
-CONFIG_VIDEOBUF2_MEMOPS=m
-CONFIG_VIDEOBUF2_DMA_CONTIG=m
-CONFIG_VIDEOBUF2_VMALLOC=m
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
-CONFIG_VIDEO_IR_I2C=m
-
-#
-# Encoders, decoders, sensors and other helper chips
-#
-
-#
-# Audio decoders, processors and mixers
-#
-CONFIG_VIDEO_TVAUDIO=m
-CONFIG_VIDEO_TDA7432=m
-CONFIG_VIDEO_TDA9840=m
-CONFIG_VIDEO_TEA6415C=m
-CONFIG_VIDEO_TEA6420=m
-CONFIG_VIDEO_MSP3400=m
-CONFIG_VIDEO_CS5345=m
-CONFIG_VIDEO_CS53L32A=m
-CONFIG_VIDEO_TLV320AIC23B=m
-CONFIG_VIDEO_WM8775=m
-CONFIG_VIDEO_WM8739=m
-CONFIG_VIDEO_VP27SMPX=m
-
-#
-# RDS decoders
-#
-CONFIG_VIDEO_SAA6588=m
-
-#
-# Video decoders
-#
-CONFIG_VIDEO_ADV7180=m
-CONFIG_VIDEO_BT819=m
-CONFIG_VIDEO_BT856=m
-CONFIG_VIDEO_BT866=m
-CONFIG_VIDEO_KS0127=m
-CONFIG_VIDEO_SAA7110=m
-CONFIG_VIDEO_SAA711X=m
-CONFIG_VIDEO_SAA7191=m
-CONFIG_VIDEO_TVP514X=m
-CONFIG_VIDEO_TVP5150=m
-CONFIG_VIDEO_TVP7002=m
-CONFIG_VIDEO_VPX3220=m
-
-#
-# Video and audio decoders
-#
-CONFIG_VIDEO_SAA717X=m
-CONFIG_VIDEO_CX25840=m
-
-#
-# MPEG video encoders
-#
-CONFIG_VIDEO_CX2341X=m
-
-#
-# Video encoders
-#
-CONFIG_VIDEO_SAA7127=m
-CONFIG_VIDEO_SAA7185=m
-CONFIG_VIDEO_ADV7170=m
-CONFIG_VIDEO_ADV7175=m
-CONFIG_VIDEO_ADV7343=m
-CONFIG_VIDEO_AK881X=m
-
-#
-# Camera sensor devices
-#
-CONFIG_VIDEO_OV7670=m
-CONFIG_VIDEO_MT9P031=m
-CONFIG_VIDEO_MT9T001=m
-CONFIG_VIDEO_MT9V011=m
-CONFIG_VIDEO_MT9V032=m
-CONFIG_VIDEO_TCM825X=m
-# CONFIG_VIDEO_SR030PC30 is not set
-CONFIG_VIDEO_NOON010PC30=m
-# CONFIG_VIDEO_M5MOLS is not set
-CONFIG_VIDEO_S5K6AA=m
-
-#
-# Flash devices
-#
-# CONFIG_VIDEO_ADP1653 is not set
-
-#
-# Video improvement chips
-#
-CONFIG_VIDEO_UPD64031A=m
-CONFIG_VIDEO_UPD64083=m
-
-#
-# Miscelaneous helper chips
-#
-CONFIG_VIDEO_THS7303=m
-CONFIG_VIDEO_M52790=m
-# CONFIG_VIDEO_VIVI is not set
-CONFIG_VIDEO_BT848=m
-CONFIG_VIDEO_BT848_DVB=y
-CONFIG_VIDEO_BWQCAM=m
-CONFIG_VIDEO_CQCAM=m
-# CONFIG_VIDEO_CPIA2 is not set
-CONFIG_VIDEO_ZORAN=m
-CONFIG_VIDEO_ZORAN_DC30=m
-CONFIG_VIDEO_ZORAN_ZR36060=m
-CONFIG_VIDEO_ZORAN_BUZ=m
-CONFIG_VIDEO_ZORAN_DC10=m
-CONFIG_VIDEO_ZORAN_LML33=m
-CONFIG_VIDEO_ZORAN_LML33R10=m
-CONFIG_VIDEO_ZORAN_AVS6EYES=m
-CONFIG_VIDEO_MEYE=m
-CONFIG_VIDEO_SAA7134=m
-CONFIG_VIDEO_SAA7134_ALSA=m
-CONFIG_VIDEO_SAA7134_RC=y
-CONFIG_VIDEO_SAA7134_DVB=m
-CONFIG_VIDEO_MXB=m
-CONFIG_VIDEO_HEXIUM_ORION=m
-CONFIG_VIDEO_HEXIUM_GEMINI=m
-CONFIG_VIDEO_TIMBERDALE=m
-CONFIG_VIDEO_CX88=m
-CONFIG_VIDEO_CX88_ALSA=m
-CONFIG_VIDEO_CX88_BLACKBIRD=m
-CONFIG_VIDEO_CX88_DVB=m
-CONFIG_VIDEO_CX88_MPEG=m
-CONFIG_VIDEO_CX88_VP3054=m
-CONFIG_VIDEO_CX23885=m
-# CONFIG_MEDIA_ALTERA_CI is not set
-# CONFIG_VIDEO_CX25821 is not set
-CONFIG_VIDEO_AU0828=m
-CONFIG_VIDEO_IVTV=m
-CONFIG_VIDEO_FB_IVTV=m
-CONFIG_VIDEO_CX18=m
-CONFIG_VIDEO_CX18_ALSA=m
-CONFIG_VIDEO_SAA7164=m
-CONFIG_VIDEO_CAFE_CCIC=m
-# CONFIG_VIDEO_VIA_CAMERA is not set
-CONFIG_SOC_CAMERA=m
-# CONFIG_SOC_CAMERA_IMX074 is not set
-CONFIG_SOC_CAMERA_MT9M001=m
-CONFIG_SOC_CAMERA_MT9M111=m
-CONFIG_SOC_CAMERA_MT9T031=m
-CONFIG_SOC_CAMERA_MT9T112=m
-CONFIG_SOC_CAMERA_MT9V022=m
-CONFIG_SOC_CAMERA_RJ54N1=m
-CONFIG_SOC_CAMERA_TW9910=m
-CONFIG_SOC_CAMERA_PLATFORM=m
-CONFIG_SOC_CAMERA_OV2640=m
-# CONFIG_SOC_CAMERA_OV5642 is not set
-# CONFIG_SOC_CAMERA_OV6650 is not set
-CONFIG_SOC_CAMERA_OV772X=m
-CONFIG_SOC_CAMERA_OV9640=m
-CONFIG_SOC_CAMERA_OV9740=m
-CONFIG_V4L_USB_DRIVERS=y
-CONFIG_USB_VIDEO_CLASS=m
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-CONFIG_USB_GSPCA=m
-CONFIG_USB_M5602=m
-CONFIG_USB_STV06XX=m
-CONFIG_USB_GL860=m
-CONFIG_USB_GSPCA_BENQ=m
-CONFIG_USB_GSPCA_CONEX=m
-CONFIG_USB_GSPCA_CPIA1=m
-CONFIG_USB_GSPCA_ETOMS=m
-CONFIG_USB_GSPCA_FINEPIX=m
-CONFIG_USB_GSPCA_JEILINJ=m
-CONFIG_USB_GSPCA_KINECT=m
-# CONFIG_USB_GSPCA_KONICA is not set
-CONFIG_USB_GSPCA_MARS=m
-CONFIG_USB_GSPCA_MR97310A=m
-CONFIG_USB_GSPCA_NW80X=m
-CONFIG_USB_GSPCA_OV519=m
-CONFIG_USB_GSPCA_OV534=m
-CONFIG_USB_GSPCA_OV534_9=m
-CONFIG_USB_GSPCA_PAC207=m
-CONFIG_USB_GSPCA_PAC7302=m
-CONFIG_USB_GSPCA_PAC7311=m
-CONFIG_USB_GSPCA_SE401=m
-CONFIG_USB_GSPCA_SN9C2028=m
-CONFIG_USB_GSPCA_SN9C20X=m
-CONFIG_USB_GSPCA_SONIXB=m
-CONFIG_USB_GSPCA_SONIXJ=m
-CONFIG_USB_GSPCA_SPCA500=m
-CONFIG_USB_GSPCA_SPCA501=m
-CONFIG_USB_GSPCA_SPCA505=m
-CONFIG_USB_GSPCA_SPCA506=m
-CONFIG_USB_GSPCA_SPCA508=m
-CONFIG_USB_GSPCA_SPCA561=m
-# CONFIG_USB_GSPCA_SPCA1528 is not set
-CONFIG_USB_GSPCA_SQ905=m
-CONFIG_USB_GSPCA_SQ905C=m
-# CONFIG_USB_GSPCA_SQ930X is not set
-CONFIG_USB_GSPCA_STK014=m
-CONFIG_USB_GSPCA_STV0680=m
-CONFIG_USB_GSPCA_SUNPLUS=m
-CONFIG_USB_GSPCA_T613=m
-CONFIG_USB_GSPCA_TOPRO=m
-CONFIG_USB_GSPCA_TV8532=m
-CONFIG_USB_GSPCA_VC032X=m
-CONFIG_USB_GSPCA_VICAM=m
-# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
-CONFIG_USB_GSPCA_ZC3XX=m
-CONFIG_VIDEO_PVRUSB2=m
-CONFIG_VIDEO_PVRUSB2_SYSFS=y
-CONFIG_VIDEO_PVRUSB2_DVB=y
-# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
-CONFIG_VIDEO_HDPVR=m
-CONFIG_VIDEO_EM28XX=m
-CONFIG_VIDEO_EM28XX_ALSA=m
-CONFIG_VIDEO_EM28XX_DVB=m
-CONFIG_VIDEO_EM28XX_RC=y
-CONFIG_VIDEO_TLG2300=m
-CONFIG_VIDEO_CX231XX=m
-CONFIG_VIDEO_CX231XX_RC=y
-CONFIG_VIDEO_CX231XX_ALSA=m
-CONFIG_VIDEO_CX231XX_DVB=m
-# CONFIG_VIDEO_TM6000 is not set
-CONFIG_VIDEO_USBVISION=m
-CONFIG_USB_ET61X251=m
-CONFIG_USB_SN9C102=m
-# CONFIG_USB_PWC is not set
-CONFIG_USB_ZR364XX=m
-CONFIG_USB_STKWEBCAM=m
-CONFIG_USB_S2255=m
-CONFIG_V4L_MEM2MEM_DRIVERS=y
-CONFIG_VIDEO_MEM2MEM_TESTDEV=m
-CONFIG_RADIO_ADAPTERS=y
-CONFIG_RADIO_MAXIRADIO=m
-# CONFIG_I2C_SI4713 is not set
-# CONFIG_RADIO_SI4713 is not set
-CONFIG_USB_DSBR=m
-# CONFIG_RADIO_SI470X is not set
-CONFIG_USB_MR800=m
-CONFIG_RADIO_TEA5764=m
-CONFIG_RADIO_SAA7706H=m
-CONFIG_RADIO_TEF6862=m
-CONFIG_RADIO_TIMBERDALE=m
-CONFIG_RADIO_WL1273=m
-
-#
-# Texas Instruments WL128x FM driver (ST based)
-#
-CONFIG_RADIO_WL128X=m
-CONFIG_DVB_MAX_ADAPTERS=8
-# CONFIG_DVB_DYNAMIC_MINORS is not set
-CONFIG_DVB_CAPTURE_DRIVERS=y
-
-#
-# Supported SAA7146 based PCI Adapters
-#
-CONFIG_TTPCI_EEPROM=m
-CONFIG_DVB_AV7110=m
-CONFIG_DVB_AV7110_OSD=y
-CONFIG_DVB_BUDGET_CORE=m
-CONFIG_DVB_BUDGET=m
-CONFIG_DVB_BUDGET_CI=m
-CONFIG_DVB_BUDGET_AV=m
-CONFIG_DVB_BUDGET_PATCH=m
-
-#
-# Supported USB Adapters
-#
-CONFIG_DVB_USB=m
-# CONFIG_DVB_USB_DEBUG is not set
-CONFIG_DVB_USB_A800=m
-CONFIG_DVB_USB_DIBUSB_MB=m
-# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
-CONFIG_DVB_USB_DIBUSB_MC=m
-CONFIG_DVB_USB_DIB0700=m
-CONFIG_DVB_USB_UMT_010=m
-CONFIG_DVB_USB_CXUSB=m
-CONFIG_DVB_USB_M920X=m
-CONFIG_DVB_USB_GL861=m
-CONFIG_DVB_USB_AU6610=m
-CONFIG_DVB_USB_DIGITV=m
-CONFIG_DVB_USB_VP7045=m
-CONFIG_DVB_USB_VP702X=m
-CONFIG_DVB_USB_GP8PSK=m
-CONFIG_DVB_USB_NOVA_T_USB2=m
-CONFIG_DVB_USB_TTUSB2=m
-CONFIG_DVB_USB_DTT200U=m
-CONFIG_DVB_USB_OPERA1=m
-CONFIG_DVB_USB_AF9005=m
-CONFIG_DVB_USB_AF9005_REMOTE=m
-CONFIG_DVB_USB_PCTV452E=m
-CONFIG_DVB_USB_DW2102=m
-CONFIG_DVB_USB_CINERGY_T2=m
-CONFIG_DVB_USB_ANYSEE=m
-CONFIG_DVB_USB_DTV5100=m
-CONFIG_DVB_USB_AF9015=m
-CONFIG_DVB_USB_CE6230=m
-# CONFIG_DVB_USB_FRIIO is not set
-CONFIG_DVB_USB_EC168=m
-CONFIG_DVB_USB_AZ6027=m
-# CONFIG_DVB_USB_LME2510 is not set
-CONFIG_DVB_USB_TECHNISAT_USB2=m
-CONFIG_DVB_USB_IT913X=m
-CONFIG_DVB_USB_MXL111SF=m
-CONFIG_DVB_TTUSB_BUDGET=m
-CONFIG_DVB_TTUSB_DEC=m
-CONFIG_SMS_SIANO_MDTV=m
-
-#
-# Siano module components
-#
-CONFIG_SMS_USB_DRV=m
-CONFIG_SMS_SDIO_DRV=m
-
-#
-# Supported FlexCopII (B2C2) Adapters
-#
-CONFIG_DVB_B2C2_FLEXCOP=m
-CONFIG_DVB_B2C2_FLEXCOP_PCI=m
-CONFIG_DVB_B2C2_FLEXCOP_USB=m
-# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
-
-#
-# Supported BT878 Adapters
-#
-CONFIG_DVB_BT8XX=m
-
-#
-# Supported Pluto2 Adapters
-#
-CONFIG_DVB_PLUTO2=m
-
-#
-# Supported SDMC DM1105 Adapters
-#
-CONFIG_DVB_DM1105=m
-
-#
-# Supported FireWire (IEEE 1394) Adapters
-#
-CONFIG_DVB_FIREDTV=m
-CONFIG_DVB_FIREDTV_INPUT=y
-
-#
-# Supported Earthsoft PT1 Adapters
-#
-# CONFIG_DVB_PT1 is not set
-
-#
-# Supported Mantis Adapters
-#
-CONFIG_MANTIS_CORE=m
-CONFIG_DVB_MANTIS=m
-CONFIG_DVB_HOPPER=m
-
-#
-# Supported nGene Adapters
-#
-CONFIG_DVB_NGENE=m
-
-#
-# Supported ddbridge ('Octopus') Adapters
-#
-CONFIG_DVB_DDBRIDGE=m
-
-#
-# Supported DVB Frontends
-#
-# CONFIG_DVB_FE_CUSTOMISE is not set
-
-#
-# Multistandard (satellite) frontends
-#
-CONFIG_DVB_STB0899=m
-CONFIG_DVB_STB6100=m
-CONFIG_DVB_STV090x=m
-CONFIG_DVB_STV6110x=m
-
-#
-# Multistandard (cable + terrestrial) frontends
-#
-CONFIG_DVB_DRXK=m
-CONFIG_DVB_TDA18271C2DD=m
-
-#
-# DVB-S (satellite) frontends
-#
-CONFIG_DVB_CX24110=m
-CONFIG_DVB_CX24123=m
-CONFIG_DVB_MT312=m
-CONFIG_DVB_ZL10036=m
-CONFIG_DVB_ZL10039=m
-CONFIG_DVB_S5H1420=m
-CONFIG_DVB_STV0288=m
-CONFIG_DVB_STB6000=m
-CONFIG_DVB_STV0299=m
-CONFIG_DVB_STV6110=m
-CONFIG_DVB_STV0900=m
-CONFIG_DVB_TDA8083=m
-CONFIG_DVB_TDA10086=m
-CONFIG_DVB_TDA8261=m
-CONFIG_DVB_VES1X93=m
-CONFIG_DVB_TUNER_ITD1000=m
-CONFIG_DVB_TUNER_CX24113=m
-CONFIG_DVB_TDA826X=m
-CONFIG_DVB_TUA6100=m
-CONFIG_DVB_CX24116=m
-CONFIG_DVB_SI21XX=m
-CONFIG_DVB_DS3000=m
-CONFIG_DVB_MB86A16=m
-CONFIG_DVB_TDA10071=m
-
-#
-# DVB-T (terrestrial) frontends
-#
-CONFIG_DVB_SP8870=m
-CONFIG_DVB_SP887X=m
-CONFIG_DVB_CX22700=m
-CONFIG_DVB_CX22702=m
-CONFIG_DVB_DRXD=m
-CONFIG_DVB_L64781=m
-CONFIG_DVB_TDA1004X=m
-CONFIG_DVB_NXT6000=m
-CONFIG_DVB_MT352=m
-CONFIG_DVB_ZL10353=m
-CONFIG_DVB_DIB3000MB=m
-CONFIG_DVB_DIB3000MC=m
-CONFIG_DVB_DIB7000M=m
-CONFIG_DVB_DIB7000P=m
-CONFIG_DVB_TDA10048=m
-CONFIG_DVB_AF9013=m
-CONFIG_DVB_EC100=m
-CONFIG_DVB_STV0367=m
-CONFIG_DVB_CXD2820R=m
-
-#
-# DVB-C (cable) frontends
-#
-CONFIG_DVB_VES1820=m
-CONFIG_DVB_TDA10021=m
-CONFIG_DVB_TDA10023=m
-CONFIG_DVB_STV0297=m
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-CONFIG_DVB_NXT200X=m
-CONFIG_DVB_OR51211=m
-CONFIG_DVB_OR51132=m
-CONFIG_DVB_BCM3510=m
-CONFIG_DVB_LGDT330X=m
-CONFIG_DVB_LGDT3305=m
-CONFIG_DVB_S5H1409=m
-CONFIG_DVB_AU8522=m
-CONFIG_DVB_S5H1411=m
-
-#
-# ISDB-T (terrestrial) frontends
-#
-CONFIG_DVB_S921=m
-CONFIG_DVB_DIB8000=m
-CONFIG_DVB_MB86A20S=m
-
-#
-# Digital terrestrial only tuners/PLL
-#
-CONFIG_DVB_PLL=m
-CONFIG_DVB_TUNER_DIB0070=m
-CONFIG_DVB_TUNER_DIB0090=m
-
-#
-# SEC control devices for DVB-S
-#
-CONFIG_DVB_LNBP21=m
-CONFIG_DVB_LNBP22=m
-CONFIG_DVB_ISL6405=m
-CONFIG_DVB_ISL6421=m
-CONFIG_DVB_ISL6423=m
-CONFIG_DVB_A8293=m
-CONFIG_DVB_LGS8GXX=m
-CONFIG_DVB_ATBM8830=m
-CONFIG_DVB_TDA665x=m
-CONFIG_DVB_IT913X_FE=m
-
-#
-# Tools to develop new frontends
-#
-# CONFIG_DVB_DUMMY_FE is not set
-
-#
-# Graphics support
-#
-CONFIG_AGP=m
-CONFIG_AGP_AMD64=m
-CONFIG_AGP_INTEL=m
-CONFIG_AGP_SIS=m
-CONFIG_AGP_VIA=m
-# CONFIG_VGA_ARB is not set
-CONFIG_VGA_SWITCHEROO=y
-CONFIG_DRM=m
-CONFIG_DRM_KMS_HELPER=m
-CONFIG_DRM_TTM=m
-CONFIG_DRM_TDFX=m
-CONFIG_DRM_R128=m
-CONFIG_DRM_RADEON=m
-# CONFIG_DRM_RADEON_KMS is not set
-CONFIG_DRM_I810=m
-CONFIG_DRM_I915=m
-# CONFIG_DRM_I915_KMS is not set
-CONFIG_DRM_MGA=m
-CONFIG_DRM_SIS=m
-CONFIG_DRM_VIA=m
-CONFIG_DRM_SAVAGE=m
-CONFIG_DRM_VMWGFX=m
-# CONFIG_STUB_POULSBO is not set
-CONFIG_VGASTATE=m
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=m
-# CONFIG_FIRMWARE_EDID is not set
-CONFIG_FB_DDC=m
-# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-CONFIG_FB_CFB_FILLRECT=m
-CONFIG_FB_CFB_COPYAREA=m
-CONFIG_FB_CFB_IMAGEBLIT=m
-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-CONFIG_FB_SYS_FILLRECT=m
-CONFIG_FB_SYS_COPYAREA=m
-CONFIG_FB_SYS_IMAGEBLIT=m
-# CONFIG_FB_FOREIGN_ENDIAN is not set
-CONFIG_FB_SYS_FOPS=m
-# CONFIG_FB_WMT_GE_ROPS is not set
-CONFIG_FB_DEFERRED_IO=y
-CONFIG_FB_HECUBA=m
-CONFIG_FB_SVGALIB=m
-# CONFIG_FB_MACMODES is not set
-CONFIG_FB_BACKLIGHT=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-
-#
-# Frame buffer hardware drivers
-#
-CONFIG_FB_CIRRUS=m
-CONFIG_FB_PM2=m
-CONFIG_FB_PM2_FIFO_DISCONNECT=y
-CONFIG_FB_CYBER2000=m
-CONFIG_FB_CYBER2000_DDC=y
-CONFIG_FB_ARC=m
-CONFIG_FB_VGA16=m
-CONFIG_FB_UVESA=m
-CONFIG_FB_N411=m
-CONFIG_FB_HGA=m
-CONFIG_FB_S1D13XXX=m
-CONFIG_FB_NVIDIA=m
-CONFIG_FB_NVIDIA_I2C=y
-# CONFIG_FB_NVIDIA_DEBUG is not set
-CONFIG_FB_NVIDIA_BACKLIGHT=y
-CONFIG_FB_RIVA=m
-CONFIG_FB_RIVA_I2C=y
-# CONFIG_FB_RIVA_DEBUG is not set
-CONFIG_FB_RIVA_BACKLIGHT=y
-CONFIG_FB_LE80578=m
-CONFIG_FB_CARILLO_RANCH=m
-CONFIG_FB_INTEL=m
-# CONFIG_FB_INTEL_DEBUG is not set
-CONFIG_FB_INTEL_I2C=y
-CONFIG_FB_MATROX=m
-CONFIG_FB_MATROX_MILLENIUM=y
-CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G=y
-CONFIG_FB_MATROX_I2C=m
-CONFIG_FB_MATROX_MAVEN=m
-CONFIG_FB_RADEON=m
-CONFIG_FB_RADEON_I2C=y
-CONFIG_FB_RADEON_BACKLIGHT=y
-# CONFIG_FB_RADEON_DEBUG is not set
-CONFIG_FB_ATY128=m
-CONFIG_FB_ATY128_BACKLIGHT=y
-CONFIG_FB_ATY=m
-CONFIG_FB_ATY_CT=y
-CONFIG_FB_ATY_GENERIC_LCD=y
-CONFIG_FB_ATY_GX=y
-CONFIG_FB_ATY_BACKLIGHT=y
-CONFIG_FB_S3=m
-CONFIG_FB_S3_DDC=y
-CONFIG_FB_SAVAGE=m
-CONFIG_FB_SAVAGE_I2C=y
-CONFIG_FB_SAVAGE_ACCEL=y
-CONFIG_FB_SIS=m
-CONFIG_FB_SIS_300=y
-CONFIG_FB_SIS_315=y
-CONFIG_FB_VIA=m
-# CONFIG_FB_VIA_DIRECT_PROCFS is not set
-CONFIG_FB_VIA_X_COMPATIBILITY=y
-CONFIG_FB_NEOMAGIC=m
-CONFIG_FB_KYRO=m
-CONFIG_FB_3DFX=m
-CONFIG_FB_3DFX_ACCEL=y
-CONFIG_FB_3DFX_I2C=y
-CONFIG_FB_VOODOO1=m
-CONFIG_FB_VT8623=m
-CONFIG_FB_TRIDENT=m
-CONFIG_FB_ARK=m
-CONFIG_FB_PM3=m
-CONFIG_FB_CARMINE=m
-CONFIG_FB_CARMINE_DRAM_EVAL=y
-# CONFIG_CARMINE_DRAM_CUSTOM is not set
-CONFIG_FB_GEODE=y
-CONFIG_FB_GEODE_LX=m
-CONFIG_FB_GEODE_GX=m
-CONFIG_FB_GEODE_GX1=m
-CONFIG_FB_TMIO=m
-CONFIG_FB_TMIO_ACCELL=y
-CONFIG_FB_SM501=m
-# CONFIG_FB_SMSCUFX is not set
-# CONFIG_FB_UDL is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_XEN_FBDEV_FRONTEND=m
-CONFIG_FB_METRONOME=m
-CONFIG_FB_MB862XX=m
-CONFIG_FB_MB862XX_PCI_GDC=y
-CONFIG_FB_MB862XX_I2C=y
-CONFIG_FB_BROADSHEET=m
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=m
-CONFIG_LCD_L4F00242T03=m
-CONFIG_LCD_LMS283GF05=m
-CONFIG_LCD_LTV350QV=m
-CONFIG_LCD_ILI9320=m
-CONFIG_LCD_TDO24M=m
-CONFIG_LCD_VGG2432A4=m
-CONFIG_LCD_PLATFORM=m
-CONFIG_LCD_S6E63M0=m
-# CONFIG_LCD_LD9040 is not set
-CONFIG_LCD_AMS369FG06=m
-CONFIG_BACKLIGHT_CLASS_DEVICE=m
-CONFIG_BACKLIGHT_GENERIC=m
-CONFIG_BACKLIGHT_PROGEAR=m
-CONFIG_BACKLIGHT_CARILLO_RANCH=m
-# CONFIG_BACKLIGHT_APPLE is not set
-CONFIG_BACKLIGHT_SAHARA=m
-CONFIG_BACKLIGHT_ADP8860=m
-# CONFIG_BACKLIGHT_ADP8870 is not set
-CONFIG_BACKLIGHT_PCF50633=m
-
-#
-# Display device support
-#
-CONFIG_DISPLAY_SUPPORT=m
-
-#
-# Display hardware drivers
-#
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=m
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
-CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_LOGO is not set
-CONFIG_SOUND=m
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SOUND_OSS_CORE_PRECLAIM=y
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_HWDEP=m
-CONFIG_SND_RAWMIDI=m
-CONFIG_SND_JACK=y
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_PCM_OSS_PLUGINS=y
-CONFIG_SND_SEQUENCER_OSS=y
-CONFIG_SND_HRTIMER=m
-CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
-CONFIG_SND_DYNAMIC_MINORS=y
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PROCFS is not set
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_VMASTER=y
-CONFIG_SND_DMA_SGBUF=y
-CONFIG_SND_RAWMIDI_SEQ=m
-CONFIG_SND_OPL3_LIB_SEQ=m
-# CONFIG_SND_OPL4_LIB_SEQ is not set
-# CONFIG_SND_SBAWE_SEQ is not set
-CONFIG_SND_EMU10K1_SEQ=m
-CONFIG_SND_MPU401_UART=m
-CONFIG_SND_OPL3_LIB=m
-CONFIG_SND_VX_LIB=m
-CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_DRIVERS=y
-CONFIG_SND_PCSP=m
-CONFIG_SND_DUMMY=m
-# CONFIG_SND_ALOOP is not set
-CONFIG_SND_VIRMIDI=m
-CONFIG_SND_MTPAV=m
-CONFIG_SND_MTS64=m
-CONFIG_SND_SERIAL_U16550=m
-CONFIG_SND_MPU401=m
-CONFIG_SND_PORTMAN2X4=m
-CONFIG_SND_AC97_POWER_SAVE=y
-CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
-CONFIG_SND_SB_COMMON=m
-CONFIG_SND_SB16_DSP=m
-CONFIG_SND_TEA575X=m
-CONFIG_SND_PCI=y
-CONFIG_SND_AD1889=m
-CONFIG_SND_ALS300=m
-CONFIG_SND_ALS4000=m
-CONFIG_SND_ALI5451=m
-CONFIG_SND_ASIHPI=m
-CONFIG_SND_ATIIXP=m
-CONFIG_SND_ATIIXP_MODEM=m
-CONFIG_SND_AU8810=m
-CONFIG_SND_AU8820=m
-CONFIG_SND_AU8830=m
-CONFIG_SND_AW2=m
-CONFIG_SND_AZT3328=m
-CONFIG_SND_BT87X=m
-# CONFIG_SND_BT87X_OVERCLOCK is not set
-CONFIG_SND_CA0106=m
-CONFIG_SND_CMIPCI=m
-CONFIG_SND_OXYGEN_LIB=m
-CONFIG_SND_OXYGEN=m
-CONFIG_SND_CS4281=m
-CONFIG_SND_CS46XX=m
-CONFIG_SND_CS46XX_NEW_DSP=y
-CONFIG_SND_CS5530=m
-CONFIG_SND_CS5535AUDIO=m
-CONFIG_SND_CTXFI=m
-CONFIG_SND_DARLA20=m
-CONFIG_SND_GINA20=m
-CONFIG_SND_LAYLA20=m
-CONFIG_SND_DARLA24=m
-CONFIG_SND_GINA24=m
-CONFIG_SND_LAYLA24=m
-CONFIG_SND_MONA=m
-CONFIG_SND_MIA=m
-CONFIG_SND_ECHO3G=m
-CONFIG_SND_INDIGO=m
-CONFIG_SND_INDIGOIO=m
-CONFIG_SND_INDIGODJ=m
-CONFIG_SND_INDIGOIOX=m
-CONFIG_SND_INDIGODJX=m
-CONFIG_SND_EMU10K1=m
-CONFIG_SND_EMU10K1X=m
-CONFIG_SND_ENS1370=m
-CONFIG_SND_ENS1371=m
-CONFIG_SND_ES1938=m
-CONFIG_SND_ES1968=m
-CONFIG_SND_ES1968_INPUT=y
-CONFIG_SND_ES1968_RADIO=y
-CONFIG_SND_FM801=m
-# CONFIG_SND_FM801_TEA575X_BOOL is not set
-CONFIG_SND_HDA_INTEL=m
-CONFIG_SND_HDA_PREALLOC_SIZE=4096
-CONFIG_SND_HDA_HWDEP=y
-# CONFIG_SND_HDA_RECONFIG is not set
-CONFIG_SND_HDA_INPUT_BEEP=y
-CONFIG_SND_HDA_INPUT_BEEP_MODE=0
-CONFIG_SND_HDA_INPUT_JACK=y
-# CONFIG_SND_HDA_PATCH_LOADER is not set
-CONFIG_SND_HDA_CODEC_REALTEK=y
-CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS=y
-CONFIG_SND_HDA_CODEC_ANALOG=y
-CONFIG_SND_HDA_CODEC_SIGMATEL=y
-CONFIG_SND_HDA_CODEC_VIA=y
-CONFIG_SND_HDA_CODEC_HDMI=y
-CONFIG_SND_HDA_CODEC_CIRRUS=y
-CONFIG_SND_HDA_CODEC_CONEXANT=y
-CONFIG_SND_HDA_CODEC_CA0110=y
-CONFIG_SND_HDA_CODEC_CA0132=y
-CONFIG_SND_HDA_CODEC_CMEDIA=y
-CONFIG_SND_HDA_CODEC_SI3054=y
-CONFIG_SND_HDA_GENERIC=y
-# CONFIG_SND_HDA_POWER_SAVE is not set
-CONFIG_SND_HDSP=m
-CONFIG_SND_HDSPM=m
-CONFIG_SND_ICE1712=m
-CONFIG_SND_ICE1724=m
-CONFIG_SND_INTEL8X0=m
-CONFIG_SND_INTEL8X0M=m
-CONFIG_SND_KORG1212=m
-CONFIG_SND_LOLA=m
-CONFIG_SND_LX6464ES=m
-CONFIG_SND_MAESTRO3=m
-CONFIG_SND_MAESTRO3_INPUT=y
-CONFIG_SND_MIXART=m
-CONFIG_SND_NM256=m
-CONFIG_SND_PCXHR=m
-CONFIG_SND_RIPTIDE=m
-CONFIG_SND_RME32=m
-CONFIG_SND_RME96=m
-CONFIG_SND_RME9652=m
-CONFIG_SND_SONICVIBES=m
-CONFIG_SND_TRIDENT=m
-CONFIG_SND_VIA82XX=m
-CONFIG_SND_VIA82XX_MODEM=m
-CONFIG_SND_VIRTUOSO=m
-CONFIG_SND_VX222=m
-CONFIG_SND_YMFPCI=m
-CONFIG_SND_SPI=y
-CONFIG_SND_USB=y
-CONFIG_SND_USB_AUDIO=m
-CONFIG_SND_USB_UA101=m
-CONFIG_SND_USB_USX2Y=m
-CONFIG_SND_USB_CAIAQ=m
-# CONFIG_SND_USB_CAIAQ_INPUT is not set
-CONFIG_SND_USB_US122L=m
-CONFIG_SND_USB_6FIRE=m
-CONFIG_SND_FIREWIRE=y
-CONFIG_SND_FIREWIRE_LIB=m
-CONFIG_SND_FIREWIRE_SPEAKERS=m
-CONFIG_SND_ISIGHT=m
-CONFIG_SND_PCMCIA=y
-CONFIG_SND_VXPOCKET=m
-CONFIG_SND_PDAUDIOCF=m
-CONFIG_SND_SOC=m
-# CONFIG_SND_SOC_CACHE_LZO is not set
-CONFIG_SND_SOC_I2C_AND_SPI=m
-CONFIG_SND_SOC_ALL_CODECS=m
-CONFIG_SND_SOC_WM_HUBS=m
-CONFIG_SND_SOC_AD1836=m
-CONFIG_SND_SOC_AD193X=m
-CONFIG_SND_SOC_AD73311=m
-CONFIG_SND_SOC_ADAU1373=m
-CONFIG_SND_SOC_ADAV80X=m
-CONFIG_SND_SOC_ADS117X=m
-CONFIG_SND_SOC_AK4104=m
-CONFIG_SND_SOC_AK4535=m
-CONFIG_SND_SOC_AK4641=m
-CONFIG_SND_SOC_AK4642=m
-CONFIG_SND_SOC_AK4671=m
-CONFIG_SND_SOC_ALC5623=m
-CONFIG_SND_SOC_CS42L51=m
-CONFIG_SND_SOC_CS4270=m
-CONFIG_SND_SOC_CS4271=m
-CONFIG_SND_SOC_CX20442=m
-CONFIG_SND_SOC_JZ4740_CODEC=m
-CONFIG_SND_SOC_L3=m
-CONFIG_SND_SOC_DA7210=m
-CONFIG_SND_SOC_DFBMCS320=m
-CONFIG_SND_SOC_MAX98088=m
-CONFIG_SND_SOC_MAX98095=m
-CONFIG_SND_SOC_MAX9850=m
-CONFIG_SND_SOC_PCM3008=m
-CONFIG_SND_SOC_RT5631=m
-CONFIG_SND_SOC_SGTL5000=m
-CONFIG_SND_SOC_SPDIF=m
-CONFIG_SND_SOC_SSM2602=m
-CONFIG_SND_SOC_STA32X=m
-CONFIG_SND_SOC_TLV320AIC23=m
-CONFIG_SND_SOC_TLV320AIC26=m
-CONFIG_SND_SOC_TLV320AIC32X4=m
-CONFIG_SND_SOC_TLV320AIC3X=m
-CONFIG_SND_SOC_TLV320DAC33=m
-CONFIG_SND_SOC_UDA134X=m
-CONFIG_SND_SOC_UDA1380=m
-CONFIG_SND_SOC_WL1273=m
-CONFIG_SND_SOC_WM1250_EV1=m
-CONFIG_SND_SOC_WM5100=m
-CONFIG_SND_SOC_WM8400=m
-CONFIG_SND_SOC_WM8510=m
-CONFIG_SND_SOC_WM8523=m
-CONFIG_SND_SOC_WM8580=m
-CONFIG_SND_SOC_WM8711=m
-CONFIG_SND_SOC_WM8727=m
-CONFIG_SND_SOC_WM8728=m
-CONFIG_SND_SOC_WM8731=m
-CONFIG_SND_SOC_WM8737=m
-CONFIG_SND_SOC_WM8741=m
-CONFIG_SND_SOC_WM8750=m
-CONFIG_SND_SOC_WM8753=m
-CONFIG_SND_SOC_WM8770=m
-CONFIG_SND_SOC_WM8776=m
-CONFIG_SND_SOC_WM8782=m
-CONFIG_SND_SOC_WM8804=m
-CONFIG_SND_SOC_WM8900=m
-CONFIG_SND_SOC_WM8903=m
-CONFIG_SND_SOC_WM8904=m
-CONFIG_SND_SOC_WM8940=m
-CONFIG_SND_SOC_WM8955=m
-CONFIG_SND_SOC_WM8960=m
-CONFIG_SND_SOC_WM8961=m
-CONFIG_SND_SOC_WM8962=m
-CONFIG_SND_SOC_WM8971=m
-CONFIG_SND_SOC_WM8974=m
-CONFIG_SND_SOC_WM8978=m
-CONFIG_SND_SOC_WM8983=m
-CONFIG_SND_SOC_WM8985=m
-CONFIG_SND_SOC_WM8988=m
-CONFIG_SND_SOC_WM8990=m
-CONFIG_SND_SOC_WM8991=m
-CONFIG_SND_SOC_WM8993=m
-CONFIG_SND_SOC_WM8995=m
-CONFIG_SND_SOC_WM8996=m
-CONFIG_SND_SOC_WM9081=m
-CONFIG_SND_SOC_LM4857=m
-CONFIG_SND_SOC_MAX9877=m
-CONFIG_SND_SOC_TPA6130A2=m
-CONFIG_SND_SOC_WM2000=m
-CONFIG_SND_SOC_WM9090=m
-# CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=m
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=m
-CONFIG_HIDRAW=y
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-# CONFIG_HID_PID is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-CONFIG_USB_KBD=m
-CONFIG_USB_MOUSE=m
-
-#
-# Special HID drivers
-#
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_ACRUX is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-CONFIG_HID_PRODIKEYS=m
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DRAGONRISE is not set
-# CONFIG_HID_EMS_FF is not set
-# CONFIG_HID_ELECOM is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_HOLTEK is not set
-CONFIG_HID_KEYTOUCH=m
-# CONFIG_HID_KYE is not set
-# CONFIG_HID_UCLOGIC is not set
-# CONFIG_HID_WALTOP is not set
-# CONFIG_HID_GYRATION is not set
-# CONFIG_HID_TWINHAN is not set
-# CONFIG_HID_KENSINGTON is not set
-CONFIG_HID_LCPOWER=m
-# CONFIG_HID_LOGITECH is not set
-CONFIG_HID_MAGICMOUSE=m
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MONTEREY is not set
-CONFIG_HID_MULTITOUCH=m
-# CONFIG_HID_NTRIG is not set
-CONFIG_HID_ORTEK=m
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-CONFIG_HID_PICOLCD=m
-CONFIG_HID_PICOLCD_FB=y
-CONFIG_HID_PICOLCD_BACKLIGHT=y
-CONFIG_HID_PICOLCD_LCD=y
-CONFIG_HID_PICOLCD_LEDS=y
-CONFIG_HID_PRIMAX=m
-CONFIG_HID_QUANTA=m
-CONFIG_HID_ROCCAT=m
-CONFIG_HID_ROCCAT_COMMON=m
-CONFIG_HID_ROCCAT_ARVO=m
-CONFIG_HID_ROCCAT_KONE=m
-CONFIG_HID_ROCCAT_KONEPLUS=m
-CONFIG_HID_ROCCAT_KOVAPLUS=m
-# CONFIG_HID_ROCCAT_PYRA is not set
-# CONFIG_HID_SAMSUNG is not set
-CONFIG_HID_SONY=m
-CONFIG_HID_SPEEDLINK=m
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_WACOM is not set
-# CONFIG_HID_WIIMOTE is not set
-# CONFIG_HID_ZEROPLUS is not set
-CONFIG_HID_ZYDACRON=m
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_COMMON=m
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB_ARCH_HAS_XHCI=y
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_DEVICE_CLASS=y
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG_WHITELIST is not set
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_DWC3 is not set
-CONFIG_USB_MON=m
-CONFIG_USB_WUSB=m
-CONFIG_USB_WUSB_CBAF=m
-# CONFIG_USB_WUSB_CBAF_DEBUG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_C67X00_HCD=m
-CONFIG_USB_XHCI_HCD=m
-# CONFIG_USB_XHCI_HCD_DEBUGGING is not set
-CONFIG_USB_EHCI_HCD=m
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_OXU210HP_HCD=m
-CONFIG_USB_ISP116X_HCD=m
-CONFIG_USB_ISP1760_HCD=m
-CONFIG_USB_ISP1362_HCD=m
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_OHCI_HCD_SSB=y
-# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
-# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=m
-CONFIG_USB_U132_HCD=m
-CONFIG_USB_SL811_HCD=m
-CONFIG_USB_SL811_HCD_ISO=y
-CONFIG_USB_SL811_CS=m
-CONFIG_USB_R8A66597_HCD=m
-CONFIG_USB_WHCI_HCD=m
-CONFIG_USB_HWA_HCD=m
-
-#
-# USB Device Class drivers
-#
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_WDM=m
-CONFIG_USB_TMC=m
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
-#
-
-#
-# also be needed; see USB_STORAGE Help for more info
-#
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_REALTEK=m
-CONFIG_USB_STORAGE_DATAFAB=m
-CONFIG_USB_STORAGE_FREECOM=m
-CONFIG_USB_STORAGE_ISD200=m
-CONFIG_USB_STORAGE_USBAT=m
-CONFIG_USB_STORAGE_SDDR09=m
-CONFIG_USB_STORAGE_SDDR55=m
-CONFIG_USB_STORAGE_JUMPSHOT=m
-CONFIG_USB_STORAGE_ALAUDA=m
-CONFIG_USB_STORAGE_ONETOUCH=m
-CONFIG_USB_STORAGE_KARMA=m
-CONFIG_USB_STORAGE_CYPRESS_ATACB=m
-CONFIG_USB_STORAGE_ENE_UB6250=m
-CONFIG_USB_UAS=m
-CONFIG_USB_LIBUSUAL=y
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB port drivers
-#
-CONFIG_USB_USS720=m
-CONFIG_USB_SERIAL=m
-CONFIG_USB_EZUSB=y
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_AIRCABLE=m
-CONFIG_USB_SERIAL_ARK3116=m
-CONFIG_USB_SERIAL_BELKIN=m
-CONFIG_USB_SERIAL_CH341=m
-CONFIG_USB_SERIAL_WHITEHEAT=m
-CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-CONFIG_USB_SERIAL_CP210X=m
-CONFIG_USB_SERIAL_CYPRESS_M8=m
-CONFIG_USB_SERIAL_EMPEG=m
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_FUNSOFT=m
-CONFIG_USB_SERIAL_VISOR=m
-CONFIG_USB_SERIAL_IPAQ=m
-CONFIG_USB_SERIAL_IR=m
-CONFIG_USB_SERIAL_EDGEPORT=m
-CONFIG_USB_SERIAL_EDGEPORT_TI=m
-CONFIG_USB_SERIAL_GARMIN=m
-CONFIG_USB_SERIAL_IPW=m
-CONFIG_USB_SERIAL_IUU=m
-CONFIG_USB_SERIAL_KEYSPAN_PDA=m
-CONFIG_USB_SERIAL_KEYSPAN=m
-CONFIG_USB_SERIAL_KLSI=m
-CONFIG_USB_SERIAL_KOBIL_SCT=m
-CONFIG_USB_SERIAL_MCT_U232=m
-CONFIG_USB_SERIAL_MOS7720=m
-CONFIG_USB_SERIAL_MOS7715_PARPORT=y
-CONFIG_USB_SERIAL_MOS7840=m
-CONFIG_USB_SERIAL_MOTOROLA=m
-CONFIG_USB_SERIAL_NAVMAN=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_SERIAL_OTI6858=m
-CONFIG_USB_SERIAL_QCAUX=m
-CONFIG_USB_SERIAL_QUALCOMM=m
-CONFIG_USB_SERIAL_SPCP8X5=m
-CONFIG_USB_SERIAL_HP4X=m
-CONFIG_USB_SERIAL_SAFE=m
-CONFIG_USB_SERIAL_SAFE_PADDED=y
-CONFIG_USB_SERIAL_SIEMENS_MPI=m
-CONFIG_USB_SERIAL_SIERRAWIRELESS=m
-CONFIG_USB_SERIAL_SYMBOL=m
-CONFIG_USB_SERIAL_TI=m
-CONFIG_USB_SERIAL_CYBERJACK=m
-CONFIG_USB_SERIAL_XIRCOM=m
-CONFIG_USB_SERIAL_WWAN=m
-CONFIG_USB_SERIAL_OPTION=m
-CONFIG_USB_SERIAL_OMNINET=m
-CONFIG_USB_SERIAL_OPTICON=m
-CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m
-CONFIG_USB_SERIAL_ZIO=m
-# CONFIG_USB_SERIAL_SSU100 is not set
-CONFIG_USB_SERIAL_DEBUG=m
-
-#
-# USB Miscellaneous drivers
-#
-CONFIG_USB_EMI62=m
-CONFIG_USB_EMI26=m
-CONFIG_USB_ADUTUX=m
-CONFIG_USB_SEVSEG=m
-CONFIG_USB_RIO500=m
-# CONFIG_USB_LEGOTOWER is not set
-CONFIG_USB_LCD=m
-CONFIG_USB_LED=m
-CONFIG_USB_CYPRESS_CY7C63=m
-CONFIG_USB_CYTHERM=m
-CONFIG_USB_IDMOUSE=m
-CONFIG_USB_FTDI_ELAN=m
-# CONFIG_USB_APPLEDISPLAY is not set
-CONFIG_USB_SISUSBVGA=m
-CONFIG_USB_SISUSBVGA_CON=y
-CONFIG_USB_LD=m
-# CONFIG_USB_TRANCEVIBRATOR is not set
-CONFIG_USB_IOWARRIOR=m
-CONFIG_USB_TEST=m
-CONFIG_USB_ISIGHTFW=m
-# CONFIG_USB_YUREX is not set
-CONFIG_USB_ATM=m
-CONFIG_USB_SPEEDTOUCH=m
-CONFIG_USB_CXACRU=m
-CONFIG_USB_UEAGLEATM=m
-CONFIG_USB_XUSBATM=m
-# CONFIG_USB_GADGET is not set
-
-#
-# OTG and related infrastructure
-#
-CONFIG_USB_OTG_UTILS=y
-CONFIG_USB_GPIO_VBUS=m
-CONFIG_NOP_USB_XCEIV=m
-CONFIG_UWB=m
-CONFIG_UWB_HWA=m
-CONFIG_UWB_WHCI=m
-CONFIG_UWB_I1480U=m
-CONFIG_MMC=m
-# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_UNSAFE_RESUME is not set
-# CONFIG_MMC_CLKGATE is not set
-
-#
-# MMC/SD/SDIO Card Drivers
-#
-CONFIG_MMC_BLOCK=m
-CONFIG_MMC_BLOCK_MINORS=8
-CONFIG_MMC_BLOCK_BOUNCE=y
-CONFIG_SDIO_UART=m
-CONFIG_MMC_TEST=m
-
-#
-# MMC/SD/SDIO Host Controller Drivers
-#
-CONFIG_MMC_SDHCI=m
-CONFIG_MMC_SDHCI_PCI=m
-CONFIG_MMC_RICOH_MMC=y
-CONFIG_MMC_SDHCI_PLTFM=m
-CONFIG_MMC_WBSD=m
-CONFIG_MMC_TIFM_SD=m
-# CONFIG_MMC_SPI is not set
-CONFIG_MMC_SDRICOH_CS=m
-CONFIG_MMC_CB710=m
-CONFIG_MMC_VIA_SDMMC=m
-CONFIG_MMC_VUB300=m
-# CONFIG_MMC_USHC is not set
-CONFIG_MEMSTICK=m
-# CONFIG_MEMSTICK_DEBUG is not set
-
-#
-# MemoryStick drivers
-#
-# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
-CONFIG_MSPRO_BLOCK=m
-
-#
-# MemoryStick Host Controller Drivers
-#
-CONFIG_MEMSTICK_TIFM_MS=m
-CONFIG_MEMSTICK_JMICRON_38X=m
-CONFIG_MEMSTICK_R592=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-
-#
-# LED drivers
-#
-CONFIG_LEDS_LM3530=m
-CONFIG_LEDS_NET5501=m
-CONFIG_LEDS_PCA9532=m
-# CONFIG_LEDS_PCA9532_GPIO is not set
-CONFIG_LEDS_GPIO=m
-CONFIG_LEDS_LP3944=m
-# CONFIG_LEDS_LP5521 is not set
-# CONFIG_LEDS_LP5523 is not set
-CONFIG_LEDS_CLEVO_MAIL=m
-CONFIG_LEDS_PCA955X=m
-CONFIG_LEDS_DAC124S085=m
-CONFIG_LEDS_BD2802=m
-CONFIG_LEDS_INTEL_SS4200=m
-CONFIG_LEDS_LT3593=m
-CONFIG_LEDS_DELL_NETBOOKS=m
-# CONFIG_LEDS_MC13783 is not set
-CONFIG_LEDS_TRIGGERS=y
-
-#
-# LED Triggers
-#
-CONFIG_LEDS_TRIGGER_TIMER=m
-CONFIG_LEDS_TRIGGER_HEARTBEAT=m
-CONFIG_LEDS_TRIGGER_BACKLIGHT=m
-CONFIG_LEDS_TRIGGER_GPIO=m
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
-
-#
-# iptables trigger is under Netfilter config (LED target)
-#
-CONFIG_ACCESSIBILITY=y
-# CONFIG_A11Y_BRAILLE_CONSOLE is not set
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_MAD=m
-CONFIG_INFINIBAND_USER_ACCESS=m
-CONFIG_INFINIBAND_USER_MEM=y
-CONFIG_INFINIBAND_ADDR_TRANS=y
-CONFIG_INFINIBAND_MTHCA=m
-# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
-# CONFIG_INFINIBAND_IPATH is not set
-# CONFIG_INFINIBAND_QIB is not set
-CONFIG_INFINIBAND_AMSO1100=m
-# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set
-CONFIG_INFINIBAND_CXGB3=m
-# CONFIG_INFINIBAND_CXGB3_DEBUG is not set
-CONFIG_INFINIBAND_CXGB4=m
-CONFIG_MLX4_INFINIBAND=m
-CONFIG_INFINIBAND_NES=m
-# CONFIG_INFINIBAND_NES_DEBUG is not set
-CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_CM is not set
-# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
-CONFIG_INFINIBAND_SRP=m
-CONFIG_INFINIBAND_ISER=m
-# CONFIG_EDAC is not set
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-# CONFIG_RTC_DEBUG is not set
-
-#
-# RTC interfaces
-#
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_DEV=y
-CONFIG_RTC_INTF_DEV_UIE_EMUL=y
-CONFIG_RTC_DRV_TEST=m
-
-#
-# I2C RTC drivers
-#
-CONFIG_RTC_DRV_DS1307=m
-CONFIG_RTC_DRV_DS1374=m
-CONFIG_RTC_DRV_DS1672=m
-# CONFIG_RTC_DRV_DS3232 is not set
-CONFIG_RTC_DRV_MAX6900=m
-CONFIG_RTC_DRV_RS5C372=m
-CONFIG_RTC_DRV_ISL1208=m
-# CONFIG_RTC_DRV_ISL12022 is not set
-CONFIG_RTC_DRV_X1205=m
-CONFIG_RTC_DRV_PCF8563=m
-CONFIG_RTC_DRV_PCF8583=m
-CONFIG_RTC_DRV_M41T80=m
-CONFIG_RTC_DRV_M41T80_WDT=y
-CONFIG_RTC_DRV_BQ32K=m
-CONFIG_RTC_DRV_S35390A=m
-CONFIG_RTC_DRV_FM3130=m
-CONFIG_RTC_DRV_RX8581=m
-CONFIG_RTC_DRV_RX8025=m
-CONFIG_RTC_DRV_EM3027=m
-CONFIG_RTC_DRV_RV3029C2=m
-
-#
-# SPI RTC drivers
-#
-CONFIG_RTC_DRV_M41T93=m
-CONFIG_RTC_DRV_M41T94=m
-CONFIG_RTC_DRV_DS1305=m
-CONFIG_RTC_DRV_DS1390=m
-CONFIG_RTC_DRV_MAX6902=m
-CONFIG_RTC_DRV_R9701=m
-CONFIG_RTC_DRV_RS5C348=m
-CONFIG_RTC_DRV_DS3234=m
-CONFIG_RTC_DRV_PCF2123=m
-
-#
-# Platform RTC drivers
-#
-CONFIG_RTC_DRV_CMOS=y
-CONFIG_RTC_DRV_DS1286=m
-CONFIG_RTC_DRV_DS1511=m
-CONFIG_RTC_DRV_DS1553=m
-CONFIG_RTC_DRV_DS1742=m
-CONFIG_RTC_DRV_STK17TA8=m
-CONFIG_RTC_DRV_M48T86=m
-CONFIG_RTC_DRV_M48T35=m
-CONFIG_RTC_DRV_M48T59=m
-CONFIG_RTC_DRV_MSM6242=m
-CONFIG_RTC_DRV_BQ4802=m
-CONFIG_RTC_DRV_RP5C01=m
-CONFIG_RTC_DRV_V3020=m
-CONFIG_RTC_DRV_PCF50633=m
-
-#
-# on-CPU RTC drivers
-#
-# CONFIG_RTC_DRV_MC13XXX is not set
-CONFIG_DMADEVICES=y
-# CONFIG_DMADEVICES_DEBUG is not set
-
-#
-# DMA Devices
-#
-# CONFIG_INTEL_MID_DMAC is not set
-CONFIG_INTEL_IOATDMA=m
-CONFIG_TIMB_DMA=m
-CONFIG_PCH_DMA=m
-CONFIG_DMA_ENGINE=y
-
-#
-# DMA Clients
-#
-CONFIG_NET_DMA=y
-# CONFIG_ASYNC_TX_DMA is not set
-CONFIG_DMATEST=m
-CONFIG_DCA=m
-CONFIG_AUXDISPLAY=y
-CONFIG_KS0108=m
-CONFIG_KS0108_PORT=0x378
-CONFIG_KS0108_DELAY=2
-CONFIG_CFAG12864B=m
-CONFIG_CFAG12864B_RATE=20
-CONFIG_UIO=m
-CONFIG_UIO_CIF=m
-CONFIG_UIO_PDRV=m
-CONFIG_UIO_PDRV_GENIRQ=m
-CONFIG_UIO_AEC=m
-CONFIG_UIO_SERCOS3=m
-CONFIG_UIO_PCI_GENERIC=m
-CONFIG_UIO_NETX=m
-CONFIG_VIRTIO=m
-CONFIG_VIRTIO_RING=m
-
-#
-# Virtio drivers
-#
-CONFIG_VIRTIO_PCI=m
-CONFIG_VIRTIO_BALLOON=m
-CONFIG_VIRTIO_MMIO=m
-
-#
-# Xen driver support
-#
-CONFIG_XEN_BALLOON=y
-CONFIG_XEN_SCRUB_PAGES=y
-CONFIG_XEN_DEV_EVTCHN=m
-CONFIG_XEN_BACKEND=y
-CONFIG_XENFS=m
-CONFIG_XEN_COMPAT_XENFS=y
-CONFIG_XEN_SYS_HYPERVISOR=y
-CONFIG_XEN_XENBUS_FRONTEND=y
-CONFIG_XEN_GNTDEV=m
-CONFIG_XEN_GRANT_DEV_ALLOC=m
-CONFIG_SWIOTLB_XEN=y
-CONFIG_XEN_PCIDEV_BACKEND=m
-CONFIG_STAGING=y
-# CONFIG_ET131X is not set
-# CONFIG_SLICOSS is not set
-CONFIG_USBIP_CORE=m
-CONFIG_USBIP_VHCI_HCD=m
-CONFIG_USBIP_HOST=m
-# CONFIG_USBIP_DEBUG is not set
-# CONFIG_W35UND is not set
-# CONFIG_PRISM2_USB is not set
-# CONFIG_ECHO is not set
-# CONFIG_COMEDI is not set
-# CONFIG_ASUS_OLED is not set
-# CONFIG_PANEL is not set
-# CONFIG_R8187SE is not set
-# CONFIG_RTL8192U is not set
-# CONFIG_RTL8192E is not set
-# CONFIG_R8712U is not set
-# CONFIG_RTS_PSTOR is not set
-# CONFIG_RTS5139 is not set
-# CONFIG_TRANZPORT is not set
-# CONFIG_POHMELFS is not set
-# CONFIG_IDE_PHISON is not set
-# CONFIG_LINE6_USB is not set
-CONFIG_DRM_NOUVEAU=m
-CONFIG_DRM_NOUVEAU_BACKLIGHT=y
-CONFIG_DRM_NOUVEAU_DEBUG=y
-
-#
-# I2C encoder or helper chips
-#
-# CONFIG_DRM_I2C_CH7006 is not set
-CONFIG_DRM_I2C_SIL164=m
-# CONFIG_USB_SERIAL_QUATECH2 is not set
-# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
-# CONFIG_VT6655 is not set
-# CONFIG_VT6656 is not set
-CONFIG_HYPERV_STORAGE=m
-CONFIG_HYPERV_NET=m
-CONFIG_HYPERV_MOUSE=m
-# CONFIG_VME_BUS is not set
-# CONFIG_DX_SEP is not set
-# CONFIG_IIO is not set
-# CONFIG_XVMALLOC is not set
-# CONFIG_ZRAM is not set
-# CONFIG_WLAGS49_H2 is not set
-# CONFIG_WLAGS49_H25 is not set
-# CONFIG_FB_SM7XX is not set
-# CONFIG_CRYSTALHD is not set
-# CONFIG_CXT1E1 is not set
-# CONFIG_FB_XGI is not set
-# CONFIG_ACPI_QUICKSTART is not set
-# CONFIG_SBE_2T3E3 is not set
-# CONFIG_USB_ENESTORAGE is not set
-# CONFIG_BCM_WIMAX is not set
-# CONFIG_FT1000 is not set
-
-#
-# Speakup console speech
-#
-# CONFIG_SPEAKUP is not set
-# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
-# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
-# CONFIG_DRM_PSB is not set
-# CONFIG_INTEL_MEI is not set
-# CONFIG_STAGING_MEDIA is not set
-CONFIG_X86_PLATFORM_DEVICES=y
-CONFIG_ACER_WMI=m
-CONFIG_ACERHDF=m
-CONFIG_ASUS_LAPTOP=m
-CONFIG_DELL_LAPTOP=m
-CONFIG_DELL_WMI=m
-CONFIG_DELL_WMI_AIO=m
-CONFIG_FUJITSU_LAPTOP=m
-# CONFIG_FUJITSU_LAPTOP_DEBUG is not set
-CONFIG_HP_ACCEL=m
-CONFIG_HP_WMI=m
-CONFIG_MSI_LAPTOP=m
-CONFIG_PANASONIC_LAPTOP=m
-CONFIG_COMPAL_LAPTOP=m
-CONFIG_SONY_LAPTOP=m
-# CONFIG_SONYPI_COMPAT is not set
-CONFIG_IDEAPAD_LAPTOP=m
-CONFIG_THINKPAD_ACPI=m
-CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y
-# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set
-# CONFIG_THINKPAD_ACPI_DEBUG is not set
-# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set
-CONFIG_THINKPAD_ACPI_VIDEO=y
-CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y
-CONFIG_SENSORS_HDAPS=m
-CONFIG_INTEL_MENLOW=m
-CONFIG_EEEPC_LAPTOP=m
-CONFIG_ASUS_WMI=m
-CONFIG_ASUS_NB_WMI=m
-CONFIG_EEEPC_WMI=m
-CONFIG_ACPI_WMI=m
-CONFIG_MSI_WMI=m
-CONFIG_ACPI_ASUS=m
-# CONFIG_TOPSTAR_LAPTOP is not set
-CONFIG_ACPI_TOSHIBA=m
-CONFIG_TOSHIBA_BT_RFKILL=m
-CONFIG_ACPI_CMPC=m
-# CONFIG_INTEL_IPS is not set
-# CONFIG_IBM_RTL is not set
-CONFIG_XO15_EBOOK=m
-# CONFIG_SAMSUNG_LAPTOP is not set
-CONFIG_MXM_WMI=m
-CONFIG_INTEL_OAKTRAIL=m
-# CONFIG_SAMSUNG_Q10 is not set
-
-#
-# Hardware Spinlock drivers
-#
-CONFIG_CLKEVT_I8253=y
-CONFIG_I8253_LOCK=y
-CONFIG_CLKBLD_I8253=y
-CONFIG_IOMMU_API=y
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_AMD_IOMMU=y
-CONFIG_AMD_IOMMU_STATS=y
-CONFIG_DMAR_TABLE=y
-CONFIG_INTEL_IOMMU=y
-# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set
-CONFIG_INTEL_IOMMU_FLOPPY_WA=y
-CONFIG_IRQ_REMAP=y
-CONFIG_VIRT_DRIVERS=y
-CONFIG_HYPERV=m
-CONFIG_HYPERV_UTILS=m
-# CONFIG_PM_DEVFREQ is not set
-
-#
-# Firmware Drivers
-#
-CONFIG_EDD=m
-# CONFIG_EDD_OFF is not set
-CONFIG_FIRMWARE_MEMMAP=y
-CONFIG_DELL_RBU=m
-CONFIG_DCDBAS=m
-CONFIG_DMIID=y
-# CONFIG_DMI_SYSFS is not set
-# CONFIG_ISCSI_IBFT_FIND is not set
-# CONFIG_SIGMA is not set
-# CONFIG_GOOGLE_FIRMWARE is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=m
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT2_FS_XIP=y
-CONFIG_EXT3_FS=m
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_XATTR=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_EXT4_FS=m
-CONFIG_EXT4_FS_XATTR=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-# CONFIG_EXT4_DEBUG is not set
-CONFIG_FS_XIP=y
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_JBD2=m
-# CONFIG_JBD2_DEBUG is not set
-CONFIG_FS_MBCACHE=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-CONFIG_REISERFS_PROC_INFO=y
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-# CONFIG_REISERFS_FS_SECURITY is not set
-CONFIG_JFS_FS=m
-CONFIG_JFS_POSIX_ACL=y
-CONFIG_JFS_SECURITY=y
-# CONFIG_JFS_DEBUG is not set
-CONFIG_JFS_STATISTICS=y
-CONFIG_XFS_FS=m
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_XFS_RT=y
-# CONFIG_XFS_DEBUG is not set
-CONFIG_GFS2_FS=m
-CONFIG_GFS2_FS_LOCKING_DLM=y
-CONFIG_OCFS2_FS=m
-CONFIG_OCFS2_FS_O2CB=m
-CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
-CONFIG_OCFS2_FS_STATS=y
-CONFIG_OCFS2_DEBUG_MASKLOG=y
-# CONFIG_OCFS2_DEBUG_FS is not set
-CONFIG_BTRFS_FS=m
-CONFIG_BTRFS_FS_POSIX_ACL=y
-CONFIG_NILFS2_FS=m
-CONFIG_FS_POSIX_ACL=y
-CONFIG_EXPORTFS=m
-CONFIG_FILE_LOCKING=y
-CONFIG_FSNOTIFY=y
-# CONFIG_DNOTIFY is not set
-CONFIG_INOTIFY_USER=y
-# CONFIG_FANOTIFY is not set
-CONFIG_QUOTA=y
-CONFIG_QUOTA_NETLINK_INTERFACE=y
-# CONFIG_PRINT_QUOTA_WARNING is not set
-# CONFIG_QUOTA_DEBUG is not set
-CONFIG_QUOTA_TREE=m
-CONFIG_QFMT_V1=m
-CONFIG_QFMT_V2=m
-CONFIG_QUOTACTL=y
-CONFIG_QUOTACTL_COMPAT=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-# CONFIG_CUSE is not set
-
-#
-# Caches
-#
-CONFIG_FSCACHE=m
-CONFIG_FSCACHE_STATS=y
-CONFIG_FSCACHE_HISTOGRAM=y
-# CONFIG_FSCACHE_DEBUG is not set
-# CONFIG_FSCACHE_OBJECT_LIST is not set
-CONFIG_CACHEFILES=m
-# CONFIG_CACHEFILES_DEBUG is not set
-# CONFIG_CACHEFILES_HISTOGRAM is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_DEBUG is not set
-CONFIG_NTFS_RW=y
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-CONFIG_PROC_SYSCTL=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_TMPFS_XATTR is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_CONFIGFS_FS=m
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-CONFIG_ECRYPT_FS=m
-CONFIG_HFS_FS=m
-CONFIG_HFSPLUS_FS=m
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EFS_FS=m
-CONFIG_JFFS2_FS=m
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_FS_POSIX_ACL=y
-CONFIG_JFFS2_FS_SECURITY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RTIME=y
-CONFIG_JFFS2_RUBIN=y
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
-CONFIG_UBIFS_FS=m
-# CONFIG_UBIFS_FS_XATTR is not set
-# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
-CONFIG_UBIFS_FS_LZO=y
-CONFIG_UBIFS_FS_ZLIB=y
-# CONFIG_UBIFS_FS_DEBUG is not set
-CONFIG_LOGFS=m
-CONFIG_CRAMFS=m
-CONFIG_SQUASHFS=m
-CONFIG_SQUASHFS_XATTR=y
-CONFIG_SQUASHFS_ZLIB=y
-# CONFIG_SQUASHFS_LZO is not set
-CONFIG_SQUASHFS_XZ=y
-# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
-# CONFIG_SQUASHFS_EMBEDDED is not set
-CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
-# CONFIG_VXFS_FS is not set
-CONFIG_MINIX_FS=m
-CONFIG_OMFS_FS=m
-CONFIG_HPFS_FS=m
-# CONFIG_QNX4FS_FS is not set
-CONFIG_ROMFS_FS=m
-CONFIG_ROMFS_BACKED_BY_BLOCK=y
-# CONFIG_ROMFS_BACKED_BY_MTD is not set
-# CONFIG_ROMFS_BACKED_BY_BOTH is not set
-CONFIG_ROMFS_ON_BLOCK=y
-CONFIG_PSTORE=y
-CONFIG_SYSV_FS=m
-CONFIG_UFS_FS=m
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_UFS_DEBUG is not set
-CONFIG_EXOFS_FS=m
-# CONFIG_EXOFS_DEBUG is not set
-CONFIG_ORE=m
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-CONFIG_NFS_V4=y
-# CONFIG_NFS_V4_1 is not set
-# CONFIG_NFS_FSCACHE is not set
-# CONFIG_NFS_USE_LEGACY_DNS is not set
-CONFIG_NFS_USE_KERNEL_DNS=y
-# CONFIG_NFS_USE_NEW_IDMAPPER is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-CONFIG_NFSD_V4=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-CONFIG_SUNRPC_XPRT_RDMA=m
-CONFIG_RPCSEC_GSS_KRB5=m
-CONFIG_CEPH_FS=m
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_UPCALL is not set
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_DEBUG2 is not set
-CONFIG_CIFS_DFS_UPCALL=y
-# CONFIG_CIFS_FSCACHE is not set
-CONFIG_CIFS_ACL=y
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-CONFIG_DLM=m
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Kernel hacking
-#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_PRINTK_TIME=y
-CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
-CONFIG_ENABLE_WARN_DEPRECATED=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=1024
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_SECTION_MISMATCH is not set
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SHIRQ=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_HARDLOCKUP_DETECTOR=y
-# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-# CONFIG_DETECT_HUNG_TASK is not set
-CONFIG_SCHED_DEBUG=y
-CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_KMEMLEAK is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_SPARSE_RCU_POINTER is not set
-# CONFIG_LOCK_STAT is not set
-# CONFIG_DEBUG_ATOMIC_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_VIRTUAL is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_TEST_LIST_SORT is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_DEBUG_CREDENTIALS is not set
-CONFIG_ARCH_WANT_FRAME_POINTERS=y
-CONFIG_FRAME_POINTER=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-CONFIG_RCU_CPU_STALL_TIMEOUT=60
-# CONFIG_KPROBES_SANITY_TEST is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
-# CONFIG_DEBUG_PER_CPU_MAPS is not set
-# CONFIG_LKDTM is not set
-# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
-# CONFIG_FAULT_INJECTION is not set
-CONFIG_LATENCYTOP=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-# CONFIG_DEBUG_PAGEALLOC is not set
-CONFIG_USER_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
-CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_RING_BUFFER=y
-CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING_SUPPORT=y
-# CONFIG_FTRACE is not set
-# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
-# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_DMA_API_DEBUG is not set
-# CONFIG_ATOMIC64_SELFTEST is not set
-# CONFIG_ASYNC_RAID6_TEST is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-CONFIG_HAVE_ARCH_KMEMCHECK=y
-CONFIG_TEST_KSTRTOX=m
-CONFIG_STRICT_DEVMEM=y
-# CONFIG_X86_VERBOSE_BOOTUP is not set
-# CONFIG_EARLY_PRINTK is not set
-CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_X86_PTDUMP is not set
-CONFIG_DEBUG_RODATA=y
-# CONFIG_DEBUG_RODATA_TEST is not set
-CONFIG_DEBUG_SET_MODULE_RONX=y
-CONFIG_DEBUG_NX_TEST=m
-# CONFIG_IOMMU_DEBUG is not set
-# CONFIG_IOMMU_STRESS is not set
-CONFIG_HAVE_MMIOTRACE_SUPPORT=y
-CONFIG_X86_DECODER_SELFTEST=y
-CONFIG_IO_DELAY_TYPE_0X80=0
-CONFIG_IO_DELAY_TYPE_0XED=1
-CONFIG_IO_DELAY_TYPE_UDELAY=2
-CONFIG_IO_DELAY_TYPE_NONE=3
-CONFIG_IO_DELAY_0X80=y
-# CONFIG_IO_DELAY_0XED is not set
-# CONFIG_IO_DELAY_UDELAY is not set
-# CONFIG_IO_DELAY_NONE is not set
-CONFIG_DEFAULT_IO_DELAY_TYPE=0
-CONFIG_DEBUG_BOOT_PARAMS=y
-# CONFIG_CPA_DEBUG is not set
-# CONFIG_OPTIMIZE_INLINING is not set
-# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-CONFIG_TRUSTED_KEYS=m
-CONFIG_ENCRYPTED_KEYS=m
-# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
-# CONFIG_SECURITY_DMESG_RESTRICT is not set
-CONFIG_SECURITY=y
-CONFIG_SECURITYFS=y
-# CONFIG_SECURITY_NETWORK is not set
-# CONFIG_SECURITY_PATH is not set
-# CONFIG_INTEL_TXT is not set
-# CONFIG_SECURITY_TOMOYO is not set
-# CONFIG_SECURITY_APPARMOR is not set
-# CONFIG_IMA is not set
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_XOR_BLOCKS=m
-CONFIG_ASYNC_CORE=m
-CONFIG_ASYNC_MEMCPY=m
-CONFIG_ASYNC_XOR=m
-CONFIG_ASYNC_PQ=m
-CONFIG_ASYNC_RAID6_RECOV=m
-CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y
-CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ALGAPI2=y
-CONFIG_CRYPTO_AEAD=m
-CONFIG_CRYPTO_AEAD2=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_BLKCIPHER2=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_RNG=m
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_PCOMP=m
-CONFIG_CRYPTO_PCOMP2=y
-CONFIG_CRYPTO_MANAGER=m
-CONFIG_CRYPTO_MANAGER2=y
-CONFIG_CRYPTO_USER=m
-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_PCRYPT=m
-CONFIG_CRYPTO_WORKQUEUE=y
-CONFIG_CRYPTO_CRYPTD=m
-CONFIG_CRYPTO_AUTHENC=m
-CONFIG_CRYPTO_TEST=m
-
-#
-# Authenticated Encryption with Associated Data
-#
-CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
-CONFIG_CRYPTO_SEQIV=m
-
-#
-# Block modes
-#
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_CTR=m
-CONFIG_CRYPTO_CTS=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
-
-#
-# Hash modes
-#
-CONFIG_CRYPTO_HMAC=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_VMAC=m
-
-#
-# Digest
-#
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CRC32C_INTEL=m
-CONFIG_CRYPTO_GHASH=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_RMD128=m
-CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_RMD256=m
-CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA1_SSSE3=m
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m
-
-#
-# Ciphers
-#
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_AES_X86_64=m
-CONFIG_CRYPTO_AES_NI_INTEL=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_BLOWFISH_COMMON=m
-CONFIG_CRYPTO_BLOWFISH_X86_64=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SALSA20=m
-CONFIG_CRYPTO_SALSA20_X86_64=m
-CONFIG_CRYPTO_SEED=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_TWOFISH_X86_64=m
-CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m
-
-#
-# Compression
-#
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_ZLIB=m
-CONFIG_CRYPTO_LZO=m
-
-#
-# Random Number Generation
-#
-CONFIG_CRYPTO_ANSI_CPRNG=m
-CONFIG_CRYPTO_USER_API=m
-CONFIG_CRYPTO_USER_API_HASH=m
-CONFIG_CRYPTO_USER_API_SKCIPHER=m
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_DEV_PADLOCK=m
-CONFIG_CRYPTO_DEV_PADLOCK_AES=m
-CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
-CONFIG_HAVE_KVM=y
-CONFIG_HAVE_KVM_IRQCHIP=y
-CONFIG_HAVE_KVM_EVENTFD=y
-CONFIG_KVM_APIC_ARCHITECTURE=y
-CONFIG_KVM_MMIO=y
-CONFIG_KVM_ASYNC_PF=y
-CONFIG_VIRTUALIZATION=y
-CONFIG_KVM=m
-CONFIG_KVM_INTEL=m
-CONFIG_KVM_AMD=m
-CONFIG_VHOST_NET=m
-# CONFIG_BINARY_PRINTF is not set
-
-#
-# Library routines
-#
-CONFIG_RAID6_PQ=m
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
-CONFIG_CRC_T10DIF=m
-CONFIG_CRC_ITU_T=m
-CONFIG_CRC32=y
-CONFIG_CRC7=m
-CONFIG_LIBCRC32C=m
-CONFIG_CRC8=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_XZ_DEC=y
-CONFIG_XZ_DEC_X86=y
-CONFIG_XZ_DEC_POWERPC=y
-CONFIG_XZ_DEC_IA64=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_SPARC=y
-CONFIG_XZ_DEC_BCJ=y
-# CONFIG_XZ_DEC_TEST is not set
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_DECOMPRESS_XZ=y
-CONFIG_DECOMPRESS_LZO=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_REED_SOLOMON=m
-CONFIG_REED_SOLOMON_DEC16=y
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_BTREE=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_CHECK_SIGNATURE=y
-CONFIG_CPU_RMAP=y
-CONFIG_NLATTR=y
-CONFIG_AVERAGE=y
-CONFIG_CORDIC=m
diff --git a/main/linux-scst/scst-2.2.0-3.2.2.patch b/main/linux-scst/scst-2.2.0-3.2.2.patch
deleted file mode 100644
index 68e90a791..000000000
--- a/main/linux-scst/scst-2.2.0-3.2.2.patch
+++ /dev/null
@@ -1,80901 +0,0 @@
-=== modified file 'block/blk-map.c'
---- old/block/blk-map.c 2012-01-10 22:58:17 +0000
-+++ new/block/blk-map.c 2012-01-10 23:01:21 +0000
-@@ -5,6 +5,8 @@
- #include <linux/module.h>
- #include <linux/bio.h>
- #include <linux/blkdev.h>
-+#include <linux/scatterlist.h>
-+#include <linux/slab.h>
- #include <scsi/sg.h> /* for struct sg_iovec */
-
- #include "blk.h"
-@@ -275,6 +277,339 @@ int blk_rq_unmap_user(struct bio *bio)
- }
- EXPORT_SYMBOL(blk_rq_unmap_user);
-
-+struct blk_kern_sg_work {
-+ atomic_t bios_inflight;
-+ struct sg_table sg_table;
-+ struct scatterlist *src_sgl;
-+};
-+
-+static void blk_free_kern_sg_work(struct blk_kern_sg_work *bw)
-+{
-+ struct sg_table *sgt = &bw->sg_table;
-+ struct scatterlist *sg;
-+ int i;
-+
-+ for_each_sg(sgt->sgl, sg, sgt->orig_nents, i) {
-+ struct page *pg = sg_page(sg);
-+ if (pg == NULL)
-+ break;
-+ __free_page(pg);
-+ }
-+
-+ sg_free_table(sgt);
-+ kfree(bw);
-+ return;
-+}
-+
-+static void blk_bio_map_kern_endio(struct bio *bio, int err)
-+{
-+ struct blk_kern_sg_work *bw = bio->bi_private;
-+
-+ if (bw != NULL) {
-+ /* Decrement the bios in processing and, if zero, free */
-+ BUG_ON(atomic_read(&bw->bios_inflight) <= 0);
-+ if (atomic_dec_and_test(&bw->bios_inflight)) {
-+ if ((bio_data_dir(bio) == READ) && (err == 0)) {
-+ unsigned long flags;
-+
-+ local_irq_save(flags); /* to protect KMs */
-+ sg_copy(bw->src_sgl, bw->sg_table.sgl, 0, 0,
-+ KM_BIO_DST_IRQ, KM_BIO_SRC_IRQ);
-+ local_irq_restore(flags);
-+ }
-+ blk_free_kern_sg_work(bw);
-+ }
-+ }
-+
-+ bio_put(bio);
-+ return;
-+}
-+
-+static int blk_rq_copy_kern_sg(struct request *rq, struct scatterlist *sgl,
-+ int nents, struct blk_kern_sg_work **pbw,
-+ gfp_t gfp, gfp_t page_gfp)
-+{
-+ int res = 0, i;
-+ struct scatterlist *sg;
-+ struct scatterlist *new_sgl;
-+ int new_sgl_nents;
-+ size_t len = 0, to_copy;
-+ struct blk_kern_sg_work *bw;
-+
-+ bw = kzalloc(sizeof(*bw), gfp);
-+ if (bw == NULL)
-+ goto out;
-+
-+ bw->src_sgl = sgl;
-+
-+ for_each_sg(sgl, sg, nents, i)
-+ len += sg->length;
-+ to_copy = len;
-+
-+ new_sgl_nents = PFN_UP(len);
-+
-+ res = sg_alloc_table(&bw->sg_table, new_sgl_nents, gfp);
-+ if (res != 0)
-+ goto err_free;
-+
-+ new_sgl = bw->sg_table.sgl;
-+
-+ for_each_sg(new_sgl, sg, new_sgl_nents, i) {
-+ struct page *pg;
-+
-+ pg = alloc_page(page_gfp);
-+ if (pg == NULL)
-+ goto err_free;
-+
-+ sg_assign_page(sg, pg);
-+ sg->length = min_t(size_t, PAGE_SIZE, len);
-+
-+ len -= PAGE_SIZE;
-+ }
-+
-+ if (rq_data_dir(rq) == WRITE) {
-+ /*
-+ * We need to limit amount of copied data to to_copy, because
-+ * sgl might have the last element in sgl not marked as last in
-+ * SG chaining.
-+ */
-+ sg_copy(new_sgl, sgl, 0, to_copy,
-+ KM_USER0, KM_USER1);
-+ }
-+
-+ *pbw = bw;
-+ /*
-+ * REQ_COPY_USER name is misleading. It should be something like
-+ * REQ_HAS_TAIL_SPACE_FOR_PADDING.
-+ */
-+ rq->cmd_flags |= REQ_COPY_USER;
-+
-+out:
-+ return res;
-+
-+err_free:
-+ blk_free_kern_sg_work(bw);
-+ res = -ENOMEM;
-+ goto out;
-+}
-+
-+static int __blk_rq_map_kern_sg(struct request *rq, struct scatterlist *sgl,
-+ int nents, struct blk_kern_sg_work *bw, gfp_t gfp)
-+{
-+ int res;
-+ struct request_queue *q = rq->q;
-+ int rw = rq_data_dir(rq);
-+ int max_nr_vecs, i;
-+ size_t tot_len;
-+ bool need_new_bio;
-+ struct scatterlist *sg, *prev_sg = NULL;
-+ struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
-+ int bios;
-+
-+ if (unlikely((sgl == NULL) || (sgl->length == 0) || (nents <= 0))) {
-+ WARN_ON(1);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ /*
-+ * Let's keep each bio allocation inside a single page to decrease
-+ * probability of failure.
-+ */
-+ max_nr_vecs = min_t(size_t,
-+ ((PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec)),
-+ BIO_MAX_PAGES);
-+
-+ need_new_bio = true;
-+ tot_len = 0;
-+ bios = 0;
-+ for_each_sg(sgl, sg, nents, i) {
-+ struct page *page = sg_page(sg);
-+ void *page_addr = page_address(page);
-+ size_t len = sg->length, l;
-+ size_t offset = sg->offset;
-+
-+ tot_len += len;
-+ prev_sg = sg;
-+
-+ /*
-+ * Each segment must be aligned on DMA boundary and
-+ * not on stack. The last one may have unaligned
-+ * length as long as the total length is aligned to
-+ * DMA padding alignment.
-+ */
-+ if (i == nents - 1)
-+ l = 0;
-+ else
-+ l = len;
-+ if (((sg->offset | l) & queue_dma_alignment(q)) ||
-+ (page_addr && object_is_on_stack(page_addr + sg->offset))) {
-+ res = -EINVAL;
-+ goto out_free_bios;
-+ }
-+
-+ while (len > 0) {
-+ size_t bytes;
-+ int rc;
-+
-+ if (need_new_bio) {
-+ bio = bio_kmalloc(gfp, max_nr_vecs);
-+ if (bio == NULL) {
-+ res = -ENOMEM;
-+ goto out_free_bios;
-+ }
-+
-+ if (rw == WRITE)
-+ bio->bi_rw |= REQ_WRITE;
-+
-+ bios++;
-+ bio->bi_private = bw;
-+ bio->bi_end_io = blk_bio_map_kern_endio;
-+
-+ if (hbio == NULL)
-+ hbio = tbio = bio;
-+ else
-+ tbio = tbio->bi_next = bio;
-+ }
-+
-+ bytes = min_t(size_t, len, PAGE_SIZE - offset);
-+
-+ rc = bio_add_pc_page(q, bio, page, bytes, offset);
-+ if (rc < bytes) {
-+ if (unlikely(need_new_bio || (rc < 0))) {
-+ if (rc < 0)
-+ res = rc;
-+ else
-+ res = -EIO;
-+ goto out_free_bios;
-+ } else {
-+ need_new_bio = true;
-+ len -= rc;
-+ offset += rc;
-+ continue;
-+ }
-+ }
-+
-+ need_new_bio = false;
-+ offset = 0;
-+ len -= bytes;
-+ page = nth_page(page, 1);
-+ }
-+ }
-+
-+ if (hbio == NULL) {
-+ res = -EINVAL;
-+ goto out_free_bios;
-+ }
-+
-+ /* Total length must be aligned on DMA padding alignment */
-+ if ((tot_len & q->dma_pad_mask) &&
-+ !(rq->cmd_flags & REQ_COPY_USER)) {
-+ res = -EINVAL;
-+ goto out_free_bios;
-+ }
-+
-+ if (bw != NULL)
-+ atomic_set(&bw->bios_inflight, bios);
-+
-+ while (hbio != NULL) {
-+ bio = hbio;
-+ hbio = hbio->bi_next;
-+ bio->bi_next = NULL;
-+
-+ blk_queue_bounce(q, &bio);
-+
-+ res = blk_rq_append_bio(q, rq, bio);
-+ if (unlikely(res != 0)) {
-+ bio->bi_next = hbio;
-+ hbio = bio;
-+ /* We can have one or more bios bounced */
-+ goto out_unmap_bios;
-+ }
-+ }
-+
-+ res = 0;
-+
-+ rq->buffer = NULL;
-+out:
-+ return res;
-+
-+out_unmap_bios:
-+ blk_rq_unmap_kern_sg(rq, res);
-+
-+out_free_bios:
-+ while (hbio != NULL) {
-+ bio = hbio;
-+ hbio = hbio->bi_next;
-+ bio_put(bio);
-+ }
-+ goto out;
-+}
-+
-+/**
-+ * blk_rq_map_kern_sg - map kernel data to a request, for REQ_TYPE_BLOCK_PC
-+ * @rq: request to fill
-+ * @sgl: area to map
-+ * @nents: number of elements in @sgl
-+ * @gfp: memory allocation flags
-+ *
-+ * Description:
-+ * Data will be mapped directly if possible. Otherwise a bounce
-+ * buffer will be used.
-+ */
-+int blk_rq_map_kern_sg(struct request *rq, struct scatterlist *sgl,
-+ int nents, gfp_t gfp)
-+{
-+ int res;
-+
-+ res = __blk_rq_map_kern_sg(rq, sgl, nents, NULL, gfp);
-+ if (unlikely(res != 0)) {
-+ struct blk_kern_sg_work *bw = NULL;
-+
-+ res = blk_rq_copy_kern_sg(rq, sgl, nents, &bw,
-+ gfp, rq->q->bounce_gfp | gfp);
-+ if (unlikely(res != 0))
-+ goto out;
-+
-+ res = __blk_rq_map_kern_sg(rq, bw->sg_table.sgl,
-+ bw->sg_table.nents, bw, gfp);
-+ if (res != 0) {
-+ blk_free_kern_sg_work(bw);
-+ goto out;
-+ }
-+ }
-+
-+ rq->buffer = NULL;
-+
-+out:
-+ return res;
-+}
-+EXPORT_SYMBOL(blk_rq_map_kern_sg);
-+
-+/**
-+ * blk_rq_unmap_kern_sg - unmap a request with kernel sg
-+ * @rq: request to unmap
-+ * @err: non-zero error code
-+ *
-+ * Description:
-+ * Unmap a rq previously mapped by blk_rq_map_kern_sg(). Must be called
-+ * only in case of an error!
-+ */
-+void blk_rq_unmap_kern_sg(struct request *rq, int err)
-+{
-+ struct bio *bio = rq->bio;
-+
-+ while (bio) {
-+ struct bio *b = bio;
-+ bio = bio->bi_next;
-+ b->bi_end_io(b, err);
-+ }
-+ rq->bio = NULL;
-+
-+ return;
-+}
-+EXPORT_SYMBOL(blk_rq_unmap_kern_sg);
-+
- /**
- * blk_rq_map_kern - map kernel data to a request, for REQ_TYPE_BLOCK_PC usage
- * @q: request queue where request should be inserted
-
-=== modified file 'include/linux/blkdev.h'
---- old/include/linux/blkdev.h 2012-01-10 22:58:17 +0000
-+++ new/include/linux/blkdev.h 2012-01-10 23:01:21 +0000
-@@ -716,6 +718,9 @@ extern int blk_rq_map_kern(struct reques
- extern int blk_rq_map_user_iov(struct request_queue *, struct request *,
- struct rq_map_data *, struct sg_iovec *, int,
- unsigned int, gfp_t);
-+extern int blk_rq_map_kern_sg(struct request *rq, struct scatterlist *sgl,
-+ int nents, gfp_t gfp);
-+extern void blk_rq_unmap_kern_sg(struct request *rq, int err);
- extern int blk_execute_rq(struct request_queue *, struct gendisk *,
- struct request *, int);
- extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *,
-
-=== modified file 'include/linux/scatterlist.h'
---- old/include/linux/scatterlist.h 2012-01-10 22:58:17 +0000
-+++ new/include/linux/scatterlist.h 2012-01-10 23:01:21 +0000
-@@ -3,6 +3,7 @@
-
- #include <asm/types.h>
- #include <asm/scatterlist.h>
-+#include <asm/kmap_types.h>
- #include <linux/mm.h>
- #include <linux/string.h>
- #include <asm/io.h>
-@@ -218,6 +219,10 @@ size_t sg_copy_from_buffer(struct scatte
- size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,
- void *buf, size_t buflen);
-
-+int sg_copy(struct scatterlist *dst_sg, struct scatterlist *src_sg,
-+ int nents_to_copy, size_t copy_len,
-+ enum km_type d_km_type, enum km_type s_km_type);
-+
- /*
- * Maximum number of entries that will be allocated in one piece, if
- * a list larger than this is required then chaining will be utilized.
-
-=== modified file 'lib/scatterlist.c'
---- old/lib/scatterlist.c 2012-01-10 22:58:17 +0000
-+++ new/lib/scatterlist.c 2012-01-10 23:01:21 +0000
-@@ -517,3 +517,132 @@ size_t sg_copy_to_buffer(struct scatterl
- return sg_copy_buffer(sgl, nents, buf, buflen, 1);
- }
- EXPORT_SYMBOL(sg_copy_to_buffer);
-+
-+/*
-+ * Can switch to the next dst_sg element, so, to copy to strictly only
-+ * one dst_sg element, it must be either last in the chain, or
-+ * copy_len == dst_sg->length.
-+ */
-+static int sg_copy_elem(struct scatterlist **pdst_sg, size_t *pdst_len,
-+ size_t *pdst_offs, struct scatterlist *src_sg,
-+ size_t copy_len,
-+ enum km_type d_km_type, enum km_type s_km_type)
-+{
-+ int res = 0;
-+ struct scatterlist *dst_sg;
-+ size_t src_len, dst_len, src_offs, dst_offs;
-+ struct page *src_page, *dst_page;
-+
-+ dst_sg = *pdst_sg;
-+ dst_len = *pdst_len;
-+ dst_offs = *pdst_offs;
-+ dst_page = sg_page(dst_sg);
-+
-+ src_page = sg_page(src_sg);
-+ src_len = src_sg->length;
-+ src_offs = src_sg->offset;
-+
-+ do {
-+ void *saddr, *daddr;
-+ size_t n;
-+
-+ saddr = kmap_atomic(src_page +
-+ (src_offs >> PAGE_SHIFT), s_km_type) +
-+ (src_offs & ~PAGE_MASK);
-+ daddr = kmap_atomic(dst_page +
-+ (dst_offs >> PAGE_SHIFT), d_km_type) +
-+ (dst_offs & ~PAGE_MASK);
-+
-+ if (((src_offs & ~PAGE_MASK) == 0) &&
-+ ((dst_offs & ~PAGE_MASK) == 0) &&
-+ (src_len >= PAGE_SIZE) && (dst_len >= PAGE_SIZE) &&
-+ (copy_len >= PAGE_SIZE)) {
-+ copy_page(daddr, saddr);
-+ n = PAGE_SIZE;
-+ } else {
-+ n = min_t(size_t, PAGE_SIZE - (dst_offs & ~PAGE_MASK),
-+ PAGE_SIZE - (src_offs & ~PAGE_MASK));
-+ n = min(n, src_len);
-+ n = min(n, dst_len);
-+ n = min_t(size_t, n, copy_len);
-+ memcpy(daddr, saddr, n);
-+ }
-+ dst_offs += n;
-+ src_offs += n;
-+
-+ kunmap_atomic(saddr, s_km_type);
-+ kunmap_atomic(daddr, d_km_type);
-+
-+ res += n;
-+ copy_len -= n;
-+ if (copy_len == 0)
-+ goto out;
-+
-+ src_len -= n;
-+ dst_len -= n;
-+ if (dst_len == 0) {
-+ dst_sg = sg_next(dst_sg);
-+ if (dst_sg == NULL)
-+ goto out;
-+ dst_page = sg_page(dst_sg);
-+ dst_len = dst_sg->length;
-+ dst_offs = dst_sg->offset;
-+ }
-+ } while (src_len > 0);
-+
-+out:
-+ *pdst_sg = dst_sg;
-+ *pdst_len = dst_len;
-+ *pdst_offs = dst_offs;
-+ return res;
-+}
-+
-+/**
-+ * sg_copy - copy one SG vector to another
-+ * @dst_sg: destination SG
-+ * @src_sg: source SG
-+ * @nents_to_copy: maximum number of entries to copy
-+ * @copy_len: maximum amount of data to copy. If 0, then copy all.
-+ * @d_km_type: kmap_atomic type for the destination SG
-+ * @s_km_type: kmap_atomic type for the source SG
-+ *
-+ * Description:
-+ * Data from the source SG vector will be copied to the destination SG
-+ * vector. End of the vectors will be determined by sg_next() returning
-+ * NULL. Returns number of bytes copied.
-+ */
-+int sg_copy(struct scatterlist *dst_sg, struct scatterlist *src_sg,
-+ int nents_to_copy, size_t copy_len,
-+ enum km_type d_km_type, enum km_type s_km_type)
-+{
-+ int res = 0;
-+ size_t dst_len, dst_offs;
-+
-+ if (copy_len == 0)
-+ copy_len = 0x7FFFFFFF; /* copy all */
-+
-+ if (nents_to_copy == 0)
-+ nents_to_copy = 0x7FFFFFFF; /* copy all */
-+
-+ dst_len = dst_sg->length;
-+ dst_offs = dst_sg->offset;
-+
-+ do {
-+ int copied = sg_copy_elem(&dst_sg, &dst_len, &dst_offs,
-+ src_sg, copy_len, d_km_type, s_km_type);
-+ copy_len -= copied;
-+ res += copied;
-+ if ((copy_len == 0) || (dst_sg == NULL))
-+ goto out;
-+
-+ nents_to_copy--;
-+ if (nents_to_copy == 0)
-+ goto out;
-+
-+ src_sg = sg_next(src_sg);
-+ } while (src_sg != NULL);
-+
-+out:
-+ return res;
-+}
-+EXPORT_SYMBOL(sg_copy);
-
-=== modified file 'include/linux/mm_types.h'
---- old/include/linux/mm_types.h 2012-01-10 22:58:17 +0000
-+++ new/include/linux/mm_types.h 2012-01-10 23:02:48 +0000
-@@ -149,6 +149,17 @@ struct page {
- */
- void *shadow;
- #endif
-+
-+#if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
-+ /*
-+ * Used to implement support for notification on zero-copy TCP transfer
-+ * completion. It might look as not good to have this field here and
-+ * it's better to have it in struct sk_buff, but it would make the code
-+ * much more complicated and fragile, since all skb then would have to
-+ * contain only pages with the same value in this field.
-+ */
-+ void *net_priv;
-+#endif
- }
- /*
- * If another subsystem starts using the double word pairing for atomic
-
-=== modified file 'include/linux/net.h'
---- old/include/linux/net.h 2012-01-10 22:58:17 +0000
-+++ new/include/linux/net.h 2012-01-10 23:02:48 +0000
-@@ -61,6 +61,7 @@ typedef enum {
- #include <linux/fcntl.h> /* For O_CLOEXEC and O_NONBLOCK */
- #include <linux/kmemcheck.h>
- #include <linux/rcupdate.h>
-+#include <linux/mm.h>
-
- struct poll_table_struct;
- struct pipe_inode_info;
-@@ -289,5 +290,44 @@ extern int kernel_sock_shutdown(struct s
- MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \
- "-type-" __stringify(type))
-
-+#if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
-+/* Support for notification on zero-copy TCP transfer completion */
-+typedef void (*net_get_page_callback_t)(struct page *page);
-+typedef void (*net_put_page_callback_t)(struct page *page);
-+
-+extern net_get_page_callback_t net_get_page_callback;
-+extern net_put_page_callback_t net_put_page_callback;
-+
-+extern int net_set_get_put_page_callbacks(
-+ net_get_page_callback_t get_callback,
-+ net_put_page_callback_t put_callback);
-+
-+/*
-+ * See comment for net_set_get_put_page_callbacks() why those functions
-+ * don't need any protection.
-+ */
-+static inline void net_get_page(struct page *page)
-+{
-+ if (page->net_priv != 0)
-+ net_get_page_callback(page);
-+ get_page(page);
-+}
-+static inline void net_put_page(struct page *page)
-+{
-+ if (page->net_priv != 0)
-+ net_put_page_callback(page);
-+ put_page(page);
-+}
-+#else
-+static inline void net_get_page(struct page *page)
-+{
-+ get_page(page);
-+}
-+static inline void net_put_page(struct page *page)
-+{
-+ put_page(page);
-+}
-+#endif /* CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION */
-+
- #endif /* __KERNEL__ */
- #endif /* _LINUX_NET_H */
-
-=== modified file 'include/linux/skbuff.h'
---- old/include/linux/skbuff.h 2012-01-10 22:58:17 +0000
-+++ new/include/linux/skbuff.h 2012-01-10 23:15:31 +0000
-@@ -1712,7 +1712,7 @@ static inline struct page *skb_frag_page
- */
- static inline void __skb_frag_ref(skb_frag_t *frag)
- {
-- get_page(skb_frag_page(frag));
-+ net_get_page(skb_frag_page(frag));
- }
-
- /**
-@@ -1735,7 +1735,7 @@ static inline void skb_frag_ref(struct s
- */
- static inline void __skb_frag_unref(skb_frag_t *frag)
- {
-- put_page(skb_frag_page(frag));
-+ net_put_page(skb_frag_page(frag));
- }
-
- /**
-
-=== modified file 'net/Kconfig'
---- old/net/Kconfig 2012-01-10 22:58:17 +0000
-+++ new/net/Kconfig 2012-01-10 23:02:48 +0000
-@@ -72,6 +72,18 @@ config INET
-
- Short answer: say Y.
-
-+config TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION
-+ bool "TCP/IP zero-copy transfer completion notification"
-+ depends on INET
-+ default SCST_ISCSI
-+ ---help---
-+ Adds support for sending a notification upon completion of a
-+ zero-copy TCP/IP transfer. This can speed up certain TCP/IP
-+ software. Currently this is only used by the iSCSI target driver
-+ iSCSI-SCST.
-+
-+ If unsure, say N.
-+
- if INET
- source "net/ipv4/Kconfig"
- source "net/ipv6/Kconfig"
-
-=== modified file 'net/core/skbuff.c'
---- old/net/core/skbuff.c 2012-01-10 22:58:17 +0000
-+++ new/net/core/skbuff.c 2012-01-10 23:02:48 +0000
-@@ -77,13 +77,13 @@ static struct kmem_cache *skbuff_fclone_
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
- struct pipe_buffer *buf)
- {
-- put_page(buf->page);
-+ net_put_page(buf->page);
- }
-
- static void sock_pipe_buf_get(struct pipe_inode_info *pipe,
- struct pipe_buffer *buf)
- {
-- get_page(buf->page);
-+ net_get_page(buf->page);
- }
-
- static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
-@@ -654,7 +654,7 @@ int skb_copy_ubufs(struct sk_buff *skb,
- if (!page) {
- while (head) {
- struct page *next = (struct page *)head->private;
-- put_page(head);
-+ net_put_page(head);
- head = next;
- }
- return -ENOMEM;
-@@ -1493,7 +1493,7 @@ EXPORT_SYMBOL(skb_copy_bits);
- */
- static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
- {
-- put_page(spd->pages[i]);
-+ net_put_page(spd->pages[i]);
- }
-
- static inline struct page *linear_to_page(struct page *page, unsigned int *len,
-@@ -1517,7 +1517,7 @@ new_page:
- off = sk->sk_sndmsg_off;
- mlen = PAGE_SIZE - off;
- if (mlen < 64 && mlen < *len) {
-- put_page(p);
-+ net_put_page(p);
- goto new_page;
- }
-
-@@ -1527,7 +1527,7 @@ new_page:
- memcpy(page_address(p) + off, page_address(page) + *offset, *len);
- sk->sk_sndmsg_off += *len;
- *offset = off;
-- get_page(p);
-+ net_get_page(p);
-
- return p;
- }
-@@ -1549,7 +1549,7 @@ static inline int spd_fill_page(struct s
- if (!page)
- return 1;
- } else
-- get_page(page);
-+ net_get_page(page);
-
- spd->pages[spd->nr_pages] = page;
- spd->partial[spd->nr_pages].len = *len;
-
-=== modified file 'net/ipv4/Makefile'
---- old/net/ipv4/Makefile 2012-01-10 22:58:17 +0000
-+++ new/net/ipv4/Makefile 2012-01-10 23:02:48 +0000
-@@ -48,6 +48,7 @@ obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
- obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
- obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
- obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
-+obj-$(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) += tcp_zero_copy.o
-
- obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
- xfrm4_output.o
-
-=== modified file 'net/ipv4/ip_output.c'
---- old/net/ipv4/ip_output.c 2012-01-10 22:58:17 +0000
-+++ new/net/ipv4/ip_output.c 2012-01-10 23:02:48 +0000
-@@ -1232,7 +1232,7 @@ ssize_t ip_append_page(struct sock *sk,
- if (skb_can_coalesce(skb, i, page, offset)) {
- skb_frag_size_add(&skb_shinfo(skb)->frags[i-1], len);
- } else if (i < MAX_SKB_FRAGS) {
-- get_page(page);
-+ net_get_page(page);
- skb_fill_page_desc(skb, i, page, offset, len);
- } else {
- err = -EMSGSIZE;
-
-=== modified file 'net/ipv4/tcp.c'
---- old/net/ipv4/tcp.c 2012-01-10 22:58:17 +0000
-+++ new/net/ipv4/tcp.c 2012-01-10 23:02:48 +0000
-@@ -815,7 +815,7 @@ new_segment:
- if (can_coalesce) {
- skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
- } else {
-- get_page(page);
-+ net_get_page(page);
- skb_fill_page_desc(skb, i, page, offset, copy);
- }
-
-@@ -1022,7 +1022,7 @@ new_segment:
- goto new_segment;
- } else if (page) {
- if (off == PAGE_SIZE) {
-- put_page(page);
-+ net_put_page(page);
- TCP_PAGE(sk) = page = NULL;
- off = 0;
- }
-@@ -1062,9 +1062,9 @@ new_segment:
- } else {
- skb_fill_page_desc(skb, i, page, off, copy);
- if (TCP_PAGE(sk)) {
-- get_page(page);
-+ net_get_page(page);
- } else if (off + copy < PAGE_SIZE) {
-- get_page(page);
-+ net_get_page(page);
- TCP_PAGE(sk) = page;
- }
- }
-
-=== added file 'net/ipv4/tcp_zero_copy.c'
---- old/net/ipv4/tcp_zero_copy.c 1970-01-01 00:00:00 +0000
-+++ new/net/ipv4/tcp_zero_copy.c 2012-01-10 23:43:22 +0000
-@@ -0,0 +1,50 @@
-+/*
-+ * Support routines for TCP zero copy transmit
-+ *
-+ * Created by Vladislav Bolkhovitin
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ */
-+
-+#include <linux/export.h>
-+#include <linux/skbuff.h>
-+
-+net_get_page_callback_t net_get_page_callback __read_mostly;
-+EXPORT_SYMBOL_GPL(net_get_page_callback);
-+
-+net_put_page_callback_t net_put_page_callback __read_mostly;
-+EXPORT_SYMBOL_GPL(net_put_page_callback);
-+
-+/*
-+ * Caller of this function must ensure that at the moment when it's called
-+ * there are no pages in the system with net_priv field set to non-zero
-+ * value. Hence, this function, as well as net_get_page() and net_put_page(),
-+ * don't need any protection.
-+ */
-+int net_set_get_put_page_callbacks(
-+ net_get_page_callback_t get_callback,
-+ net_put_page_callback_t put_callback)
-+{
-+ int res = 0;
-+
-+ if ((net_get_page_callback != NULL) && (get_callback != NULL) &&
-+ (net_get_page_callback != get_callback)) {
-+ res = -EBUSY;
-+ goto out;
-+ }
-+
-+ if ((net_put_page_callback != NULL) && (put_callback != NULL) &&
-+ (net_put_page_callback != put_callback)) {
-+ res = -EBUSY;
-+ goto out;
-+ }
-+
-+ net_get_page_callback = get_callback;
-+ net_put_page_callback = put_callback;
-+
-+out:
-+ return res;
-+}
-+EXPORT_SYMBOL_GPL(net_set_get_put_page_callbacks);
-
-diff --git a/drivers/Kconfig b/drivers/Kconfig
-index a2b902f..92e3d67 100644
---- orig/linux-3.2/drivers/Kconfig
-+++ linux-3.2/drivers/Kconfig
-@@ -22,6 +22,8 @@ source "drivers/ide/Kconfig"
-
- source "drivers/scsi/Kconfig"
-
-+source "drivers/scst/Kconfig"
-+
- source "drivers/ata/Kconfig"
-
- source "drivers/md/Kconfig"
-diff --git a/drivers/Makefile b/drivers/Makefile
-index b423bb1..f780114 100644
---- orig/linux-3.2/drivers/Makefile
-+++ linux-3.2/drivers/Makefile
-@@ -115,5 +115,6 @@ obj-$(CONFIG_VLYNQ) += vlynq/
- obj-$(CONFIG_STAGING) += staging/
- obj-y += platform/
- obj-y += ieee802154/
-+obj-$(CONFIG_SCST) += scst/
- #common clk code
- obj-y += clk/
-diff -uprN orig/linux-3.2/drivers/scst/Kconfig linux-3.2/drivers/scst/Kconfig
---- orig/linux-3.2/drivers/scst/Kconfig
-+++ linux-3.2/drivers/scst/Kconfig
-@@ -0,0 +1,255 @@
-+menu "SCSI target (SCST) support"
-+
-+config SCST
-+ tristate "SCSI target (SCST) support"
-+ depends on SCSI
-+ help
-+ SCSI target (SCST) is designed to provide unified, consistent
-+ interface between SCSI target drivers and Linux kernel and
-+ simplify target drivers development as much as possible. Visit
-+ http://scst.sourceforge.net for more info about it.
-+
-+config SCST_DISK
-+ tristate "SCSI target disk support"
-+ default SCST
-+ depends on SCSI && SCST
-+ help
-+ SCST pass-through device handler for disk device.
-+
-+config SCST_TAPE
-+ tristate "SCSI target tape support"
-+ default SCST
-+ depends on SCSI && SCST
-+ help
-+ SCST pass-through device handler for tape device.
-+
-+config SCST_CDROM
-+ tristate "SCSI target CDROM support"
-+ default SCST
-+ depends on SCSI && SCST
-+ help
-+ SCST pass-through device handler for CDROM device.
-+
-+config SCST_MODISK
-+ tristate "SCSI target MO disk support"
-+ default SCST
-+ depends on SCSI && SCST
-+ help
-+ SCST pass-through device handler for MO disk device.
-+
-+config SCST_CHANGER
-+ tristate "SCSI target changer support"
-+ default SCST
-+ depends on SCSI && SCST
-+ help
-+ SCST pass-through device handler for changer device.
-+
-+config SCST_PROCESSOR
-+ tristate "SCSI target processor support"
-+ default SCST
-+ depends on SCSI && SCST
-+ help
-+ SCST pass-through device handler for processor device.
-+
-+config SCST_RAID
-+ tristate "SCSI target storage array controller (RAID) support"
-+ default SCST
-+ depends on SCSI && SCST
-+ help
-+ SCST pass-through device handler for raid storage array controller (RAID) device.
-+
-+config SCST_VDISK
-+ tristate "SCSI target virtual disk and/or CDROM support"
-+ default SCST
-+ depends on SCSI && SCST
-+ help
-+ SCST device handler for virtual disk and/or CDROM device.
-+
-+config SCST_USER
-+ tristate "User-space SCSI target driver support"
-+ default SCST
-+ depends on SCSI && SCST && !HIGHMEM4G && !HIGHMEM64G
-+ help
-+ The SCST device handler scst_user allows to implement full-feature
-+ SCSI target devices in user space.
-+
-+ If unsure, say "N".
-+
-+config SCST_STRICT_SERIALIZING
-+ bool "Strict serialization"
-+ depends on SCST
-+ help
-+ Enable strict SCSI command serialization. When enabled, SCST sends
-+ all SCSI commands to the underlying SCSI device synchronously, one
-+ after one. This makes task management more reliable, at the cost of
-+ a performance penalty. This is most useful for stateful SCSI devices
-+ like tapes, where the result of the execution of a command
-+ depends on the device settings configured by previous commands. Disk
-+ and RAID devices are stateless in most cases. The current SCSI core
-+ in Linux doesn't allow to abort all commands reliably if they have
-+ been sent asynchronously to a stateful device.
-+ Enable this option if you use stateful device(s) and need as much
-+ error recovery reliability as possible.
-+
-+ If unsure, say "N".
-+
-+config SCST_STRICT_SECURITY
-+ bool "Strict security"
-+ depends on SCST
-+ help
-+ Makes SCST clear (zero-fill) allocated data buffers. Note: this has a
-+ significant performance penalty.
-+
-+ If unsure, say "N".
-+
-+config SCST_TEST_IO_IN_SIRQ
-+ bool "Allow test I/O from soft-IRQ context"
-+ depends on SCST
-+ help
-+ Allows SCST to submit selected SCSI commands (TUR and
-+ READ/WRITE) from soft-IRQ context (tasklets). Enabling it will
-+ decrease amount of context switches and slightly improve
-+ performance. The goal of this option is to be able to measure
-+ overhead of the context switches. See more info about it in
-+ README.scst.
-+
-+ WARNING! Improperly used, this option can lead you to a kernel crash!
-+
-+ If unsure, say "N".
-+
-+config SCST_ABORT_CONSIDER_FINISHED_TASKS_AS_NOT_EXISTING
-+ bool "Send back UNKNOWN TASK when an already finished task is aborted"
-+ depends on SCST
-+ help
-+ Controls which response is sent by SCST to the initiator in case
-+ the initiator attempts to abort (ABORT TASK) an already finished
-+ request. If this option is enabled, the response UNKNOWN TASK is
-+ sent back to the initiator. However, some initiators, particularly
-+ the VMware iSCSI initiator, interpret the UNKNOWN TASK response as
-+ if the target got crazy and try to RESET it. Then sometimes the
-+ initiator gets crazy itself.
-+
-+ If unsure, say "N".
-+
-+config SCST_USE_EXPECTED_VALUES
-+ bool "Prefer initiator-supplied SCSI command attributes"
-+ depends on SCST
-+ help
-+ When SCST receives a SCSI command from an initiator, such a SCSI
-+ command has both data transfer length and direction attributes.
-+ There are two possible sources for these attributes: either the
-+ values computed by SCST from its internal command translation table
-+ or the values supplied by the initiator. The former are used by
-+ default because of security reasons. Invalid initiator-supplied
-+ attributes can crash the target, especially in pass-through mode.
-+ Only consider enabling this option when SCST logs the following
-+ message: "Unknown opcode XX for YY. Should you update
-+ scst_scsi_op_table?" and when the initiator complains. Please
-+ report any unrecognized commands to scst-devel@lists.sourceforge.net.
-+
-+ If unsure, say "N".
-+
-+config SCST_EXTRACHECKS
-+ bool "Extra consistency checks"
-+ depends on SCST
-+ help
-+ Enable additional consistency checks in the SCSI middle level target
-+ code. This may be helpful for SCST developers. Enable it if you have
-+ any problems.
-+
-+ If unsure, say "N".
-+
-+config SCST_TRACING
-+ bool "Tracing support"
-+ depends on SCST
-+ default y
-+ help
-+ Enable SCSI middle level tracing support. Tracing can be controlled
-+ dynamically via sysfs interface. The traced information
-+ is sent to the kernel log and may be very helpful when analyzing
-+ the cause of a communication problem between initiator and target.
-+
-+ If unsure, say "Y".
-+
-+config SCST_DEBUG
-+ bool "Debugging support"
-+ depends on SCST
-+ select DEBUG_BUGVERBOSE
-+ help
-+ Enables support for debugging SCST. This may be helpful for SCST
-+ developers.
-+
-+ If unsure, say "N".
-+
-+config SCST_DEBUG_OOM
-+ bool "Out-of-memory debugging support"
-+ depends on SCST
-+ help
-+ Let SCST's internal memory allocation function
-+ (scst_alloc_sg_entries()) fail about once in every 10000 calls, at
-+ least if the flag __GFP_NOFAIL has not been set. This allows SCST
-+ developers to test the behavior of SCST in out-of-memory conditions.
-+ This may be helpful for SCST developers.
-+
-+ If unsure, say "N".
-+
-+config SCST_DEBUG_RETRY
-+ bool "SCSI command retry debugging support"
-+ depends on SCST
-+ help
-+ Let SCST's internal SCSI command transfer function
-+ (scst_rdy_to_xfer()) fail about once in every 100 calls. This allows
-+ SCST developers to test the behavior of SCST when SCSI queues fill
-+ up. This may be helpful for SCST developers.
-+
-+ If unsure, say "N".
-+
-+config SCST_DEBUG_SN
-+ bool "SCSI sequence number debugging support"
-+ depends on SCST
-+ help
-+ Allows to test SCSI command ordering via sequence numbers by
-+ randomly changing the type of SCSI commands into
-+ SCST_CMD_QUEUE_ORDERED, SCST_CMD_QUEUE_HEAD_OF_QUEUE or
-+ SCST_CMD_QUEUE_SIMPLE for about one in 300 SCSI commands.
-+ This may be helpful for SCST developers.
-+
-+ If unsure, say "N".
-+
-+config SCST_DEBUG_TM
-+ bool "Task management debugging support"
-+ depends on SCST_DEBUG
-+ help
-+ Enables support for debugging of SCST's task management functions.
-+ When enabled, some of the commands on LUN 0 in the default access
-+ control group will be delayed for about 60 seconds. This will
-+ cause the remote initiator send SCSI task management functions,
-+ e.g. ABORT TASK and TARGET RESET.
-+
-+ If unsure, say "N".
-+
-+config SCST_TM_DBG_GO_OFFLINE
-+ bool "Let devices become completely unresponsive"
-+ depends on SCST_DEBUG_TM
-+ help
-+ Enable this option if you want that the device eventually becomes
-+ completely unresponsive. When disabled, the device will receive
-+ ABORT and RESET commands.
-+
-+config SCST_MEASURE_LATENCY
-+ bool "Commands processing latency measurement facility"
-+ depends on SCST
-+ help
-+ This option enables commands processing latency measurement
-+ facility in SCST. It will provide in the sysfs interface
-+ average commands processing latency statistics. You can clear
-+ already measured results by writing 0 in the corresponding sysfs file.
-+ Note, you need a non-preemtible kernel to have correct results.
-+
-+ If unsure, say "N".
-+
-+source "drivers/scst/iscsi-scst/Kconfig"
-+source "drivers/scst/scst_local/Kconfig"
-+source "drivers/scst/srpt/Kconfig"
-+
-+endmenu
-diff -uprN orig/linux-3.2/drivers/scst/Makefile linux-3.2/drivers/scst/Makefile
---- orig/linux-3.2/drivers/scst/Makefile
-+++ linux-3.2/drivers/scst/Makefile
-@@ -0,0 +1,13 @@
-+ccflags-y += -Wno-unused-parameter
-+
-+scst-y += scst_main.o
-+scst-y += scst_pres.o
-+scst-y += scst_targ.o
-+scst-y += scst_lib.o
-+scst-y += scst_sysfs.o
-+scst-y += scst_mem.o
-+scst-y += scst_tg.o
-+scst-y += scst_debug.o
-+
-+obj-$(CONFIG_SCST) += scst.o dev_handlers/ iscsi-scst/ qla2xxx-target/ \
-+ srpt/ scst_local/
-diff -uprN orig/linux-3.2/include/scst/scst.h linux-3.2/include/scst/scst.h
---- orig/linux-3.2/include/scst/scst.h
-+++ linux-3.2/include/scst/scst.h
-@@ -0,0 +1,3867 @@
-+/*
-+ * include/scst.h
-+ *
-+ * Copyright (C) 2004 - 2011 Vladislav Bolkhovitin <vst@vlnb.net>
-+ * Copyright (C) 2004 - 2005 Leonid Stoljar
-+ * Copyright (C) 2007 - 2010 ID7 Ltd.
-+ * Copyright (C) 2010 - 2011 SCST Ltd.
-+ * Copyright (C) 2010 - 2011 Bart Van Assche <bvanassche@acm.org>.
-+ *
-+ * Main SCSI target mid-level include file.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation, version 2
-+ * of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef __SCST_H
-+#define __SCST_H
-+
-+#include <linux/types.h>
-+#include <linux/blkdev.h>
-+#include <linux/interrupt.h>
-+#include <linux/wait.h>
-+#include <linux/cpumask.h>
-+
-+
-+#include <scsi/scsi_cmnd.h>
-+#include <scsi/scsi_device.h>
-+#include <scsi/scsi_eh.h>
-+#include <scsi/scsi.h>
-+
-+#include <scst/scst_const.h>
-+
-+#include <scst/scst_sgv.h>
-+
-+#define SCST_INTERFACE_VERSION \
-+ SCST_VERSION_STRING "$Revision: 3992 $" SCST_CONST_VERSION
-+
-+#define SCST_LOCAL_NAME "scst_local"
-+
-+/*************************************************************
-+ ** States of command processing state machine. At first,
-+ ** "active" states, then - "passive" ones. This is to have
-+ ** more efficient generated code of the corresponding
-+ ** "switch" statements.
-+ *************************************************************/
-+
-+/* Dev handler's parse() is going to be called */
-+#define SCST_CMD_STATE_PARSE 0
-+
-+/* Allocation of the cmd's data buffer */
-+#define SCST_CMD_STATE_PREPARE_SPACE 1
-+
-+/* Calling preprocessing_done() */
-+#define SCST_CMD_STATE_PREPROCESSING_DONE 2
-+
-+/* Target driver's rdy_to_xfer() is going to be called */
-+#define SCST_CMD_STATE_RDY_TO_XFER 3
-+
-+/* Target driver's pre_exec() is going to be called */
-+#define SCST_CMD_STATE_TGT_PRE_EXEC 4
-+
-+/* Cmd is going to be sent for execution */
-+#define SCST_CMD_STATE_SEND_FOR_EXEC 5
-+
-+/* Internal post-exec checks */
-+#define SCST_CMD_STATE_PRE_DEV_DONE 6
-+
-+/* Internal MODE SELECT pages related checks */
-+#define SCST_CMD_STATE_MODE_SELECT_CHECKS 7
-+
-+/* Dev handler's dev_done() is going to be called */
-+#define SCST_CMD_STATE_DEV_DONE 8
-+
-+/* Checks before target driver's xmit_response() is called */
-+#define SCST_CMD_STATE_PRE_XMIT_RESP 9
-+
-+/* Target driver's xmit_response() is going to be called */
-+#define SCST_CMD_STATE_XMIT_RESP 10
-+
-+/* Cmd finished */
-+#define SCST_CMD_STATE_FINISHED 11
-+
-+/* Internal cmd finished */
-+#define SCST_CMD_STATE_FINISHED_INTERNAL 12
-+
-+#define SCST_CMD_STATE_LAST_ACTIVE (SCST_CMD_STATE_FINISHED_INTERNAL+100)
-+
-+/* A cmd is created, but scst_cmd_init_done() not called */
-+#define SCST_CMD_STATE_INIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+1)
-+
-+/* LUN translation (cmd->tgt_dev assignment) */
-+#define SCST_CMD_STATE_INIT (SCST_CMD_STATE_LAST_ACTIVE+2)
-+
-+/* Waiting for scst_restart_cmd() */
-+#define SCST_CMD_STATE_PREPROCESSING_DONE_CALLED (SCST_CMD_STATE_LAST_ACTIVE+3)
-+
-+/* Waiting for data from the initiator (until scst_rx_data() called) */
-+#define SCST_CMD_STATE_DATA_WAIT (SCST_CMD_STATE_LAST_ACTIVE+4)
-+
-+/*
-+ * Cmd is ready for exec (after check if its device is blocked or should
-+ * be blocked)
-+ */
-+#define SCST_CMD_STATE_START_EXEC (SCST_CMD_STATE_LAST_ACTIVE+5)
-+
-+/* Cmd is being checked if it should be executed locally */
-+#define SCST_CMD_STATE_LOCAL_EXEC (SCST_CMD_STATE_LAST_ACTIVE+6)
-+
-+/* Cmd is ready for execution */
-+#define SCST_CMD_STATE_REAL_EXEC (SCST_CMD_STATE_LAST_ACTIVE+7)
-+
-+/* Waiting for CDB's execution finish */
-+#define SCST_CMD_STATE_REAL_EXECUTING (SCST_CMD_STATE_LAST_ACTIVE+8)
-+
-+/* Waiting for response's transmission finish */
-+#define SCST_CMD_STATE_XMIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+9)
-+
-+/*************************************************************
-+ * Can be returned instead of cmd's state by dev handlers'
-+ * functions, if the command's state should be set by default
-+ *************************************************************/
-+#define SCST_CMD_STATE_DEFAULT 500
-+
-+/*************************************************************
-+ * Can be returned instead of cmd's state by dev handlers'
-+ * functions, if it is impossible to complete requested
-+ * task in atomic context. The cmd will be restarted in thread
-+ * context.
-+ *************************************************************/
-+#define SCST_CMD_STATE_NEED_THREAD_CTX 1000
-+
-+/*************************************************************
-+ * Can be returned instead of cmd's state by dev handlers'
-+ * parse function, if the cmd processing should be stopped
-+ * for now. The cmd will be restarted by dev handlers itself.
-+ *************************************************************/
-+#define SCST_CMD_STATE_STOP 1001
-+
-+/*************************************************************
-+ ** States of mgmt command processing state machine
-+ *************************************************************/
-+
-+/* LUN translation (mcmd->tgt_dev assignment) */
-+#define SCST_MCMD_STATE_INIT 0
-+
-+/* Mgmt cmd is being processed */
-+#define SCST_MCMD_STATE_EXEC 1
-+
-+/* Waiting for affected commands done */
-+#define SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_DONE 2
-+
-+/* Post actions when affected commands done */
-+#define SCST_MCMD_STATE_AFFECTED_CMDS_DONE 3
-+
-+/* Waiting for affected local commands finished */
-+#define SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_FINISHED 4
-+
-+/* Target driver's task_mgmt_fn_done() is going to be called */
-+#define SCST_MCMD_STATE_DONE 5
-+
-+/* The mcmd finished */
-+#define SCST_MCMD_STATE_FINISHED 6
-+
-+/*************************************************************
-+ ** Constants for "atomic" parameter of SCST's functions
-+ *************************************************************/
-+#define SCST_NON_ATOMIC 0
-+#define SCST_ATOMIC 1
-+
-+/*************************************************************
-+ ** Values for pref_context parameter of scst_cmd_init_done(),
-+ ** scst_rx_data(), scst_restart_cmd(), scst_tgt_cmd_done()
-+ ** and scst_cmd_done()
-+ *************************************************************/
-+
-+enum scst_exec_context {
-+ /*
-+ * Direct cmd's processing (i.e. regular function calls in the current
-+ * context) sleeping is not allowed
-+ */
-+ SCST_CONTEXT_DIRECT_ATOMIC,
-+
-+ /*
-+ * Direct cmd's processing (i.e. regular function calls in the current
-+ * context), sleeping is allowed, no restrictions
-+ */
-+ SCST_CONTEXT_DIRECT,
-+
-+ /* Tasklet or thread context required for cmd's processing */
-+ SCST_CONTEXT_TASKLET,
-+
-+ /* Thread context required for cmd's processing */
-+ SCST_CONTEXT_THREAD,
-+
-+ /*
-+ * Context is the same as it was in previous call of the corresponding
-+ * callback. For example, if dev handler's exec() does sync. data
-+ * reading this value should be used for scst_cmd_done(). The same is
-+ * true if scst_tgt_cmd_done() called directly from target driver's
-+ * xmit_response(). Not allowed in scst_cmd_init_done() and
-+ * scst_cmd_init_stage1_done().
-+ */
-+ SCST_CONTEXT_SAME
-+};
-+
-+/*************************************************************
-+ ** Values for status parameter of scst_rx_data()
-+ *************************************************************/
-+
-+/* Success */
-+#define SCST_RX_STATUS_SUCCESS 0
-+
-+/*
-+ * Data receiving finished with error, so set the sense and
-+ * finish the command, including xmit_response() call
-+ */
-+#define SCST_RX_STATUS_ERROR 1
-+
-+/*
-+ * Data receiving finished with error and the sense is set,
-+ * so finish the command, including xmit_response() call
-+ */
-+#define SCST_RX_STATUS_ERROR_SENSE_SET 2
-+
-+/*
-+ * Data receiving finished with fatal error, so finish the command,
-+ * but don't call xmit_response()
-+ */
-+#define SCST_RX_STATUS_ERROR_FATAL 3
-+
-+/*************************************************************
-+ ** Values for status parameter of scst_restart_cmd()
-+ *************************************************************/
-+
-+/* Success */
-+#define SCST_PREPROCESS_STATUS_SUCCESS 0
-+
-+/*
-+ * Command's processing finished with error, so set the sense and
-+ * finish the command, including xmit_response() call
-+ */
-+#define SCST_PREPROCESS_STATUS_ERROR 1
-+
-+/*
-+ * Command's processing finished with error and the sense is set,
-+ * so finish the command, including xmit_response() call
-+ */
-+#define SCST_PREPROCESS_STATUS_ERROR_SENSE_SET 2
-+
-+/*
-+ * Command's processing finished with fatal error, so finish the command,
-+ * but don't call xmit_response()
-+ */
-+#define SCST_PREPROCESS_STATUS_ERROR_FATAL 3
-+
-+/*************************************************************
-+ ** Values for AEN functions
-+ *************************************************************/
-+
-+/*
-+ * SCSI Asynchronous Event. Parameter contains SCSI sense
-+ * (Unit Attention). AENs generated only for 2 the following UAs:
-+ * CAPACITY DATA HAS CHANGED and REPORTED LUNS DATA HAS CHANGED.
-+ * Other UAs reported regularly as CHECK CONDITION status,
-+ * because it doesn't look safe to report them using AENs, since
-+ * reporting using AENs opens delivery race windows even in case of
-+ * untagged commands.
-+ */
-+#define SCST_AEN_SCSI 0
-+
-+/*
-+ * Notifies that CPU affinity mask on the corresponding session changed
-+ */
-+#define SCST_AEN_CPU_MASK_CHANGED 1
-+
-+/*************************************************************
-+ ** Allowed return/status codes for report_aen() callback and
-+ ** scst_set_aen_delivery_status() function
-+ *************************************************************/
-+
-+/* Success */
-+#define SCST_AEN_RES_SUCCESS 0
-+
-+/* Not supported */
-+#define SCST_AEN_RES_NOT_SUPPORTED -1
-+
-+/* Failure */
-+#define SCST_AEN_RES_FAILED -2
-+
-+/*************************************************************
-+ ** Allowed return codes for xmit_response(), rdy_to_xfer()
-+ *************************************************************/
-+
-+/* Success */
-+#define SCST_TGT_RES_SUCCESS 0
-+
-+/* Internal device queue is full, retry again later */
-+#define SCST_TGT_RES_QUEUE_FULL -1
-+
-+/*
-+ * It is impossible to complete requested task in atomic context.
-+ * The cmd will be restarted in thread context.
-+ */
-+#define SCST_TGT_RES_NEED_THREAD_CTX -2
-+
-+/*
-+ * Fatal error, if returned by xmit_response() the cmd will
-+ * be destroyed, if by any other function, xmit_response()
-+ * will be called with HARDWARE ERROR sense data
-+ */
-+#define SCST_TGT_RES_FATAL_ERROR -3
-+
-+/*************************************************************
-+ ** Return codes for dev handler's exec()
-+ *************************************************************/
-+
-+/* The cmd is done, go to other ones */
-+#define SCST_EXEC_COMPLETED 0
-+
-+/* The cmd should be sent to SCSI mid-level */
-+#define SCST_EXEC_NOT_COMPLETED 1
-+
-+/*************************************************************
-+ ** Additional return code for dev handler's task_mgmt_fn()
-+ *************************************************************/
-+
-+/* Regular standard actions for the command should be done */
-+#define SCST_DEV_TM_NOT_COMPLETED 1
-+
-+/*************************************************************
-+ ** Session initialization phases
-+ *************************************************************/
-+
-+/* Set if session is being initialized */
-+#define SCST_SESS_IPH_INITING 0
-+
-+/* Set if the session is successfully initialized */
-+#define SCST_SESS_IPH_SUCCESS 1
-+
-+/* Set if the session initialization failed */
-+#define SCST_SESS_IPH_FAILED 2
-+
-+/* Set if session is initialized and ready */
-+#define SCST_SESS_IPH_READY 3
-+
-+/*************************************************************
-+ ** Session shutdown phases
-+ *************************************************************/
-+
-+/* Set if session is initialized and ready */
-+#define SCST_SESS_SPH_READY 0
-+
-+/* Set if session is shutting down */
-+#define SCST_SESS_SPH_SHUTDOWN 1
-+
-+/* Set if session is shutting down */
-+#define SCST_SESS_SPH_UNREG_DONE_CALLING 2
-+
-+/*************************************************************
-+ ** Session's async (atomic) flags
-+ *************************************************************/
-+
-+/* Set if the sess's hw pending work is scheduled */
-+#define SCST_SESS_HW_PENDING_WORK_SCHEDULED 0
-+
-+/*************************************************************
-+ ** Cmd's async (atomic) flags
-+ *************************************************************/
-+
-+/* Set if the cmd is aborted and ABORTED sense will be sent as the result */
-+#define SCST_CMD_ABORTED 0
-+
-+/* Set if the cmd is aborted by other initiator */
-+#define SCST_CMD_ABORTED_OTHER 1
-+
-+/* Set if no response should be sent to the target about this cmd */
-+#define SCST_CMD_NO_RESP 2
-+
-+/* Set if the cmd is dead and can be destroyed at any time */
-+#define SCST_CMD_CAN_BE_DESTROYED 3
-+
-+/*
-+ * Set if the cmd's device has TAS flag set. Used only when aborted by
-+ * other initiator.
-+ */
-+#define SCST_CMD_DEVICE_TAS 4
-+
-+/*************************************************************
-+ ** Tgt_dev's async. flags (tgt_dev_flags)
-+ *************************************************************/
-+
-+/* Set if tgt_dev has Unit Attention sense */
-+#define SCST_TGT_DEV_UA_PENDING 0
-+
-+/* Set if tgt_dev is RESERVED by another session */
-+#define SCST_TGT_DEV_RESERVED 1
-+
-+/* Set if the corresponding context should be atomic */
-+#define SCST_TGT_DEV_AFTER_INIT_WR_ATOMIC 5
-+#define SCST_TGT_DEV_AFTER_EXEC_ATOMIC 6
-+
-+#define SCST_TGT_DEV_CLUST_POOL 11
-+
-+/*************************************************************
-+ ** I/O grouping types. Changing them don't forget to change
-+ ** the corresponding *_STR values in scst_const.h!
-+ *************************************************************/
-+
-+/*
-+ * All initiators with the same name connected to this group will have
-+ * shared IO context, for each name own context. All initiators with
-+ * different names will have own IO context.
-+ */
-+#define SCST_IO_GROUPING_AUTO 0
-+
-+/* All initiators connected to this group will have shared IO context */
-+#define SCST_IO_GROUPING_THIS_GROUP_ONLY -1
-+
-+/* Each initiator connected to this group will have own IO context */
-+#define SCST_IO_GROUPING_NEVER -2
-+
-+/*************************************************************
-+ ** Kernel cache creation helper
-+ *************************************************************/
-+
-+/*************************************************************
-+ ** Valid_mask constants for scst_analyze_sense()
-+ *************************************************************/
-+
-+#define SCST_SENSE_KEY_VALID 1
-+#define SCST_SENSE_ASC_VALID 2
-+#define SCST_SENSE_ASCQ_VALID 4
-+
-+#define SCST_SENSE_ASCx_VALID (SCST_SENSE_ASC_VALID | \
-+ SCST_SENSE_ASCQ_VALID)
-+
-+#define SCST_SENSE_ALL_VALID (SCST_SENSE_KEY_VALID | \
-+ SCST_SENSE_ASC_VALID | \
-+ SCST_SENSE_ASCQ_VALID)
-+
-+/*************************************************************
-+ * TYPES
-+ *************************************************************/
-+
-+struct scst_tgt;
-+struct scst_session;
-+struct scst_cmd;
-+struct scst_mgmt_cmd;
-+struct scst_device;
-+struct scst_tgt_dev;
-+struct scst_dev_type;
-+struct scst_acg;
-+struct scst_acg_dev;
-+struct scst_acn;
-+struct scst_aen;
-+
-+/*
-+ * SCST uses 64-bit numbers to represent LUN's internally. The value
-+ * NO_SUCH_LUN is guaranteed to be different of every valid LUN.
-+ */
-+#define NO_SUCH_LUN ((uint64_t)-1)
-+
-+typedef enum dma_data_direction scst_data_direction;
-+
-+/*
-+ * SCST target template: defines target driver's parameters and callback
-+ * functions.
-+ *
-+ * MUST HAVEs define functions that are expected to be defined in order to
-+ * work. OPTIONAL says that there is a choice.
-+ */
-+struct scst_tgt_template {
-+ /* public: */
-+
-+ /*
-+ * SG tablesize allows to check whether scatter/gather can be used
-+ * or not.
-+ */
-+ int sg_tablesize;
-+
-+ /*
-+ * True, if this target adapter uses unchecked DMA onto an ISA bus.
-+ */
-+ unsigned unchecked_isa_dma:1;
-+
-+ /*
-+ * True, if this target adapter can benefit from using SG-vector
-+ * clustering (i.e. smaller number of segments).
-+ */
-+ unsigned use_clustering:1;
-+
-+ /*
-+ * True, if this target adapter doesn't support SG-vector clustering
-+ */
-+ unsigned no_clustering:1;
-+
-+ /*
-+ * True, if corresponding function supports execution in
-+ * the atomic (non-sleeping) context
-+ */
-+ unsigned xmit_response_atomic:1;
-+ unsigned rdy_to_xfer_atomic:1;
-+
-+ /* True, if this target doesn't need "enabled" attribute */
-+ unsigned enabled_attr_not_needed:1;
-+
-+ /*
-+ * True if SCST should report that it supports ACA although it does
-+ * not yet support ACA. Necessary for the IBM virtual SCSI target
-+ * driver.
-+ */
-+ unsigned fake_aca:1;
-+
-+ /*
-+ * Preferred SCSI LUN addressing method.
-+ */
-+ enum scst_lun_addr_method preferred_addr_method;
-+
-+ /*
-+ * The maximum time in seconds cmd can stay inside the target
-+ * hardware, i.e. after rdy_to_xfer() and xmit_response(), before
-+ * on_hw_pending_cmd_timeout() will be called, if defined.
-+ *
-+ * In the current implementation a cmd will be aborted in time t
-+ * max_hw_pending_time <= t < 2*max_hw_pending_time.
-+ */
-+ int max_hw_pending_time;
-+
-+ /*
-+ * This function is equivalent to the SCSI
-+ * queuecommand. The target should transmit the response
-+ * buffer and the status in the scst_cmd struct.
-+ * The expectation is that this executing this command is NON-BLOCKING.
-+ * If it is blocking, consider to set threads_num to some none 0 number.
-+ *
-+ * After the response is actually transmitted, the target
-+ * should call the scst_tgt_cmd_done() function of the
-+ * mid-level, which will allow it to free up the command.
-+ * Returns one of the SCST_TGT_RES_* constants.
-+ *
-+ * Pay attention to "atomic" attribute of the cmd, which can be get
-+ * by scst_cmd_atomic(): it is true if the function called in the
-+ * atomic (non-sleeping) context.
-+ *
-+ * MUST HAVE
-+ */
-+ int (*xmit_response) (struct scst_cmd *cmd);
-+
-+ /*
-+ * This function informs the driver that data
-+ * buffer corresponding to the said command have now been
-+ * allocated and it is OK to receive data for this command.
-+ * This function is necessary because a SCSI target does not
-+ * have any control over the commands it receives. Most lower
-+ * level protocols have a corresponding function which informs
-+ * the initiator that buffers have been allocated e.g., XFER_
-+ * RDY in Fibre Channel. After the data is actually received
-+ * the low-level driver needs to call scst_rx_data() in order to
-+ * continue processing this command.
-+ * Returns one of the SCST_TGT_RES_* constants.
-+ *
-+ * This command is expected to be NON-BLOCKING.
-+ * If it is blocking, consider to set threads_num to some none 0 number.
-+ *
-+ * Pay attention to "atomic" attribute of the cmd, which can be get
-+ * by scst_cmd_atomic(): it is true if the function called in the
-+ * atomic (non-sleeping) context.
-+ *
-+ * OPTIONAL
-+ */
-+ int (*rdy_to_xfer) (struct scst_cmd *cmd);
-+
-+ /*
-+ * Called if cmd stays inside the target hardware, i.e. after
-+ * rdy_to_xfer() and xmit_response(), more than max_hw_pending_time
-+ * time. The target driver supposed to cleanup this command and
-+ * resume cmd's processing.
-+ *
-+ * OPTIONAL
-+ */
-+ void (*on_hw_pending_cmd_timeout) (struct scst_cmd *cmd);
-+
-+ /*
-+ * Called to notify the driver that the command is about to be freed.
-+ * Necessary, because for aborted commands xmit_response() could not
-+ * be called. Could be called on IRQ context.
-+ *
-+ * OPTIONAL
-+ */
-+ void (*on_free_cmd) (struct scst_cmd *cmd);
-+
-+ /*
-+ * This function allows target driver to handle data buffer
-+ * allocations on its own.
-+ *
-+ * Target driver doesn't have to always allocate buffer in this
-+ * function, but if it decide to do it, it must check that
-+ * scst_cmd_get_data_buff_alloced() returns 0, otherwise to avoid
-+ * double buffer allocation and memory leaks alloc_data_buf() shall
-+ * fail.
-+ *
-+ * Shall return 0 in case of success or < 0 (preferably -ENOMEM)
-+ * in case of error, or > 0 if the regular SCST allocation should be
-+ * done. In case of returning successfully,
-+ * scst_cmd->tgt_data_buf_alloced will be set by SCST.
-+ *
-+ * It is possible that both target driver and dev handler request own
-+ * memory allocation. In this case, data will be memcpy() between
-+ * buffers, where necessary.
-+ *
-+ * If allocation in atomic context - cf. scst_cmd_atomic() - is not
-+ * desired or fails and consequently < 0 is returned, this function
-+ * will be re-called in thread context.
-+ *
-+ * Please note that the driver will have to handle itself all relevant
-+ * details such as scatterlist setup, highmem, freeing the allocated
-+ * memory, etc.
-+ *
-+ * OPTIONAL.
-+ */
-+ int (*alloc_data_buf) (struct scst_cmd *cmd);
-+
-+ /*
-+ * This function informs the driver that data
-+ * buffer corresponding to the said command have now been
-+ * allocated and other preprocessing tasks have been done.
-+ * A target driver could need to do some actions at this stage.
-+ * After the target driver done the needed actions, it shall call
-+ * scst_restart_cmd() in order to continue processing this command.
-+ * In case of preliminary the command completion, this function will
-+ * also be called before xmit_response().
-+ *
-+ * Called only if the cmd is queued using scst_cmd_init_stage1_done()
-+ * instead of scst_cmd_init_done().
-+ *
-+ * Returns void, the result is expected to be returned using
-+ * scst_restart_cmd().
-+ *
-+ * This command is expected to be NON-BLOCKING.
-+ * If it is blocking, consider to set threads_num to some none 0 number.
-+ *
-+ * Pay attention to "atomic" attribute of the cmd, which can be get
-+ * by scst_cmd_atomic(): it is true if the function called in the
-+ * atomic (non-sleeping) context.
-+ *
-+ * OPTIONAL.
-+ */
-+ void (*preprocessing_done) (struct scst_cmd *cmd);
-+
-+ /*
-+ * This function informs the driver that the said command is about
-+ * to be executed.
-+ *
-+ * Returns one of the SCST_PREPROCESS_* constants.
-+ *
-+ * This command is expected to be NON-BLOCKING.
-+ * If it is blocking, consider to set threads_num to some none 0 number.
-+ *
-+ * OPTIONAL
-+ */
-+ int (*pre_exec) (struct scst_cmd *cmd);
-+
-+ /*
-+ * This function informs the driver that all affected by the
-+ * corresponding task management function commands have beed completed.
-+ * No return value expected.
-+ *
-+ * This function is expected to be NON-BLOCKING.
-+ *
-+ * Called without any locks held from a thread context.
-+ *
-+ * OPTIONAL
-+ */
-+ void (*task_mgmt_affected_cmds_done) (struct scst_mgmt_cmd *mgmt_cmd);
-+
-+ /*
-+ * This function informs the driver that the corresponding task
-+ * management function has been completed, i.e. all the corresponding
-+ * commands completed and freed. No return value expected.
-+ *
-+ * This function is expected to be NON-BLOCKING.
-+ *
-+ * Called without any locks held from a thread context.
-+ *
-+ * MUST HAVE if the target supports task management.
-+ */
-+ void (*task_mgmt_fn_done) (struct scst_mgmt_cmd *mgmt_cmd);
-+
-+ /*
-+ * Called to notify target driver that the command is being aborted.
-+ * If target driver wants to redirect processing to some outside
-+ * processing, it should get it using scst_cmd_get().
-+ *
-+ * OPTIONAL
-+ */
-+ void (*on_abort_cmd) (struct scst_cmd *cmd);
-+
-+ /*
-+ * This function should detect the target adapters that
-+ * are present in the system. The function should return a value
-+ * >= 0 to signify the number of detected target adapters.
-+ * A negative value should be returned whenever there is
-+ * an error.
-+ *
-+ * MUST HAVE
-+ */
-+ int (*detect) (struct scst_tgt_template *tgt_template);
-+
-+ /*
-+ * This function should free up the resources allocated to the device.
-+ * The function should return 0 to indicate successful release
-+ * or a negative value if there are some issues with the release.
-+ * In the current version the return value is ignored.
-+ *
-+ * MUST HAVE
-+ */
-+ int (*release) (struct scst_tgt *tgt);
-+
-+ /*
-+ * This function is used for Asynchronous Event Notifications.
-+ *
-+ * Returns one of the SCST_AEN_RES_* constants.
-+ * After AEN is sent, target driver must call scst_aen_done() and,
-+ * optionally, scst_set_aen_delivery_status().
-+ *
-+ * This function is expected to be NON-BLOCKING, but can sleep.
-+ *
-+ * This function must be prepared to handle AENs between calls for the
-+ * corresponding session of scst_unregister_session() and
-+ * unreg_done_fn() callback called or before scst_unregister_session()
-+ * returned, if its called in the blocking mode. AENs for such sessions
-+ * should be ignored.
-+ *
-+ * MUST HAVE, if low-level protocol supports AENs.
-+ */
-+ int (*report_aen) (struct scst_aen *aen);
-+
-+ /*
-+ * This function returns in tr_id the corresponding to sess initiator
-+ * port TransportID in the form as it's used by PR commands, see
-+ * "Transport Identifiers" in SPC. Space for the initiator port
-+ * TransportID must be allocated via kmalloc(). Caller supposed to
-+ * kfree() it, when it isn't needed anymore.
-+ *
-+ * If sess is NULL, this function must return TransportID PROTOCOL
-+ * IDENTIFIER for the requested target.
-+ *
-+ * Returns 0 on success or negative error code otherwise.
-+ *
-+ * SHOULD HAVE, because it's required for Persistent Reservations.
-+ */
-+ int (*get_initiator_port_transport_id) (struct scst_tgt *tgt,
-+ struct scst_session *sess, uint8_t **transport_id);
-+
-+ /*
-+ * 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.
-+ *
-+ * If you are sure your target driver doesn't need enabling target,
-+ * you should set enabled_attr_not_needed in 1.
-+ */
-+ int (*enable_target) (struct scst_tgt *tgt, bool enable);
-+
-+ /*
-+ * This function shows if particular target is enabled or not.
-+ *
-+ * SHOULD HAVE, see above why.
-+ */
-+ bool (*is_target_enabled) (struct scst_tgt *tgt);
-+
-+ /*
-+ * This function adds a virtual target.
-+ *
-+ * If both add_target and del_target callbacks defined, then this
-+ * target driver supposed to support virtual targets. In this case
-+ * an "mgmt" entry will be created in the sysfs root for this driver.
-+ * The "mgmt" entry will support 2 commands: "add_target" and
-+ * "del_target", for which the corresponding callbacks will be called.
-+ * Also target driver can define own commands for the "mgmt" entry, see
-+ * mgmt_cmd and mgmt_cmd_help below.
-+ *
-+ * This approach allows uniform targets management to simplify external
-+ * management tools like scstadmin. See README for more details.
-+ *
-+ * Either both add_target and del_target must be defined, or none.
-+ *
-+ * MUST HAVE if virtual targets are supported.
-+ */
-+ ssize_t (*add_target) (const char *target_name, char *params);
-+
-+ /*
-+ * This function deletes a virtual target. See comment for add_target
-+ * above.
-+ *
-+ * MUST HAVE if virtual targets are supported.
-+ */
-+ ssize_t (*del_target) (const char *target_name);
-+
-+ /*
-+ * This function called if not "add_target" or "del_target" command is
-+ * sent to the mgmt entry (see comment for add_target above). In this
-+ * case the command passed to this function as is in a string form.
-+ *
-+ * OPTIONAL.
-+ */
-+ ssize_t (*mgmt_cmd) (char *cmd);
-+
-+ /*
-+ * Should return physical transport version. Used in the corresponding
-+ * INQUIRY version descriptor. See SPC for the list of available codes.
-+ *
-+ * OPTIONAL
-+ */
-+ uint16_t (*get_phys_transport_version) (struct scst_tgt *tgt);
-+
-+ /*
-+ * Should return SCSI transport version. Used in the corresponding
-+ * INQUIRY version descriptor. See SPC for the list of available codes.
-+ *
-+ * OPTIONAL
-+ */
-+ uint16_t (*get_scsi_transport_version) (struct scst_tgt *tgt);
-+
-+ /*
-+ * Name of the template. Must be unique to identify
-+ * the template. MUST HAVE
-+ */
-+ const char name[SCST_MAX_NAME];
-+
-+ /*
-+ * Number of additional threads to the pool of dedicated threads.
-+ * Used if xmit_response() or rdy_to_xfer() is blocking.
-+ * It is the target driver's duty to ensure that not more, than that
-+ * number of threads, are blocked in those functions at any time.
-+ */
-+ 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;
-+
-+ /* sysfs attributes, if any */
-+ const struct attribute **tgtt_attrs;
-+
-+ /* sysfs target attributes, if any */
-+ const struct attribute **tgt_attrs;
-+
-+ /* sysfs session attributes, if any */
-+ const struct attribute **sess_attrs;
-+
-+ /* Optional help string for mgmt_cmd commands */
-+ const char *mgmt_cmd_help;
-+
-+ /* List of parameters for add_target command, if any */
-+ const char *add_target_parameters;
-+
-+ /*
-+ * List of optional, i.e. which could be added by add_attribute command
-+ * and deleted by del_attribute command, sysfs attributes, if any.
-+ * Helpful for scstadmin to work correctly.
-+ */
-+ const char *tgtt_optional_attributes;
-+
-+ /*
-+ * List of optional, i.e. which could be added by add_target_attribute
-+ * command and deleted by del_target_attribute command, sysfs
-+ * attributes, if any. Helpful for scstadmin to work correctly.
-+ */
-+ const char *tgt_optional_attributes;
-+
-+ /** Private, must be inited to 0 by memset() **/
-+
-+ /* List of targets per template, protected by scst_mutex */
-+ struct list_head tgt_list;
-+
-+ /* List entry of global templates list */
-+ struct list_head scst_template_list_entry;
-+
-+ struct kobject tgtt_kobj; /* kobject for this struct */
-+
-+ /* Number of currently active sysfs mgmt works (scst_sysfs_work_item) */
-+ int tgtt_active_sysfs_works_count;
-+
-+ /* sysfs release completion */
-+ struct completion *tgtt_kobj_release_cmpl;
-+
-+ /*
-+ * Optional vendor to be reported via the SCSI inquiry data. If NULL,
-+ * an SCST device handler specific default value will be used, e.g.
-+ * "SCST_FIO" for scst_vdisk file I/O.
-+ */
-+ const char *vendor;
-+
-+ /*
-+ * Optional method that sets the product ID in [buf, buf+size) based
-+ * on the device type (byte 0 of the SCSI inquiry data, which contains
-+ * the peripheral qualifier in the highest three bits and the
-+ * peripheral device type in the lower five bits).
-+ */
-+ void (*get_product_id)(const struct scst_tgt_dev *tgt_dev,
-+ char *buf, int size);
-+
-+ /*
-+ * Optional revision to be reported in the SCSI inquiry response. If
-+ * NULL, an SCST device handler specific default value will be used,
-+ * e.g. " 220" for scst_vdisk file I/O.
-+ */
-+ const char *revision;
-+
-+ /*
-+ * Optional method that writes the serial number of a target device in
-+ * [buf, buf+size) and returns the number of bytes written.
-+ *
-+ * Note: SCST can be configured such that a device can be accessed
-+ * from several different transports at the same time. It is important
-+ * that all clients see the same USN for proper operation. Overriding
-+ * the serial number can lead to subtle misbehavior. Particularly,
-+ * "usn" sysfs attribute of the corresponding devices will still show
-+ * the devices generated or assigned serial numbers.
-+ */
-+ int (*get_serial)(const struct scst_tgt_dev *tgt_dev, char *buf,
-+ int size);
-+
-+ /*
-+ * Optional method that writes the SCSI inquiry vendor-specific data in
-+ * [buf, buf+size) and returns the number of bytes written.
-+ */
-+ int (*get_vend_specific)(const struct scst_tgt_dev *tgt_dev, char *buf,
-+ int size);
-+};
-+
-+/*
-+ * Threads pool types. Changing them don't forget to change
-+ * the corresponding *_STR values in scst_const.h!
-+ */
-+enum scst_dev_type_threads_pool_type {
-+ /* Each initiator will have dedicated threads pool. */
-+ SCST_THREADS_POOL_PER_INITIATOR = 0,
-+
-+ /* All connected initiators will use shared threads pool */
-+ SCST_THREADS_POOL_SHARED,
-+
-+ /* Invalid value for scst_parse_threads_pool_type() */
-+ SCST_THREADS_POOL_TYPE_INVALID,
-+};
-+
-+/*
-+ * SCST dev handler template: defines dev handler's parameters and callback
-+ * functions.
-+ *
-+ * MUST HAVEs define functions that are expected to be defined in order to
-+ * work. OPTIONAL says that there is a choice.
-+ */
-+struct scst_dev_type {
-+ /* SCSI type of the supported device. MUST HAVE */
-+ int type;
-+
-+ /*
-+ * True, if corresponding function supports execution in
-+ * the atomic (non-sleeping) context
-+ */
-+ unsigned parse_atomic:1;
-+ unsigned alloc_data_buf_atomic:1;
-+ unsigned dev_done_atomic:1;
-+
-+ /*
-+ * Should be true, if exec() is synchronous. This is a hint to SCST core
-+ * to optimize commands order management.
-+ */
-+ unsigned exec_sync:1;
-+
-+ /*
-+ * Should be set if the device wants to receive notification of
-+ * Persistent Reservation commands (PR OUT only)
-+ * Note: The notification will not be send if the command failed
-+ */
-+ unsigned pr_cmds_notifications:1;
-+
-+ /*
-+ * Called to parse CDB from the cmd and initialize
-+ * cmd->bufflen and cmd->data_direction (both - REQUIRED).
-+ *
-+ * Returns the command's next state or SCST_CMD_STATE_DEFAULT,
-+ * if the next default state should be used, or
-+ * SCST_CMD_STATE_NEED_THREAD_CTX if the function called in atomic
-+ * context, but requires sleeping, or SCST_CMD_STATE_STOP if the
-+ * command should not be further processed for now. In the
-+ * SCST_CMD_STATE_NEED_THREAD_CTX case the function
-+ * will be recalled in the thread context, where sleeping is allowed.
-+ *
-+ * Pay attention to "atomic" attribute of the cmd, which can be get
-+ * by scst_cmd_atomic(): it is true if the function called in the
-+ * atomic (non-sleeping) context.
-+ *
-+ * MUST HAVE
-+ */
-+ int (*parse) (struct scst_cmd *cmd);
-+
-+ /*
-+ * This function allows dev handler to handle data buffer
-+ * allocations on its own.
-+ *
-+ * Returns the command's next state or SCST_CMD_STATE_DEFAULT,
-+ * if the next default state should be used, or
-+ * SCST_CMD_STATE_NEED_THREAD_CTX if the function called in atomic
-+ * context, but requires sleeping, or SCST_CMD_STATE_STOP if the
-+ * command should not be further processed for now. In the
-+ * SCST_CMD_STATE_NEED_THREAD_CTX case the function
-+ * will be recalled in the thread context, where sleeping is allowed.
-+ *
-+ * Pay attention to "atomic" attribute of the cmd, which can be get
-+ * by scst_cmd_atomic(): it is true if the function called in the
-+ * atomic (non-sleeping) context.
-+ *
-+ * OPTIONAL
-+ */
-+ int (*alloc_data_buf) (struct scst_cmd *cmd);
-+
-+ /*
-+ * Called to execute CDB. Useful, for instance, to implement
-+ * data caching. The result of CDB execution is reported via
-+ * cmd->scst_cmd_done() callback.
-+ * Returns:
-+ * - SCST_EXEC_COMPLETED - the cmd is done, go to other ones
-+ * - SCST_EXEC_NOT_COMPLETED - the cmd should be sent to SCSI
-+ * mid-level.
-+ *
-+ * If this function provides sync execution, you should set
-+ * exec_sync flag and consider to setup dedicated threads by
-+ * setting threads_num > 0.
-+ *
-+ * !! If this function is implemented, scst_check_local_events() !!
-+ * !! shall be called inside it just before the actual command's !!
-+ * !! execution. !!
-+ *
-+ * OPTIONAL, if not set, the commands will be sent directly to SCSI
-+ * device.
-+ */
-+ int (*exec) (struct scst_cmd *cmd);
-+
-+ /*
-+ * Called to notify dev handler about the result of cmd execution
-+ * and perform some post processing. Cmd's fields is_send_status and
-+ * resp_data_len should be set by this function, but SCST offers good
-+ * defaults.
-+ * Returns the command's next state or SCST_CMD_STATE_DEFAULT,
-+ * if the next default state should be used, or
-+ * SCST_CMD_STATE_NEED_THREAD_CTX if the function called in atomic
-+ * context, but requires sleeping. In the last case, the function
-+ * will be recalled in the thread context, where sleeping is allowed.
-+ *
-+ * Pay attention to "atomic" attribute of the cmd, which can be get
-+ * by scst_cmd_atomic(): it is true if the function called in the
-+ * atomic (non-sleeping) context.
-+ *
-+ * OPTIONAL
-+ */
-+ int (*dev_done) (struct scst_cmd *cmd);
-+
-+ /*
-+ * Called to notify dev hander that the command is about to be freed.
-+ *
-+ * Could be called on IRQ context.
-+ *
-+ * OPTIONAL
-+ */
-+ void (*on_free_cmd) (struct scst_cmd *cmd);
-+
-+ /*
-+ * Called to execute a task management command.
-+ * Returns:
-+ * - SCST_MGMT_STATUS_SUCCESS - the command is done with success,
-+ * no further actions required
-+ * - The SCST_MGMT_STATUS_* error code if the command is failed and
-+ * no further actions required
-+ * - SCST_DEV_TM_NOT_COMPLETED - regular standard actions for the
-+ * command should be done
-+ *
-+ * Can be called under many internal SCST locks, including under
-+ * disabled IRQs, so dev handler should be careful with locking and,
-+ * if necessary, pass processing somewhere outside (in a work, e.g.)
-+ *
-+ * But at the moment it's called under disabled IRQs only for
-+ * SCST_ABORT_TASK, however dev handler using it should add a BUG_ON
-+ * trap to catch if it's changed in future.
-+ *
-+ * OPTIONAL
-+ */
-+ int (*task_mgmt_fn) (struct scst_mgmt_cmd *mgmt_cmd,
-+ struct scst_tgt_dev *tgt_dev);
-+
-+ /*
-+ * Called to notify dev handler that its sg_tablesize is too low to
-+ * satisfy this command's data transfer requirements. Should return
-+ * true if exec() callback will split this command's CDB on smaller
-+ * transfers, false otherwise.
-+ *
-+ * Could be called on SIRQ context.
-+ *
-+ * MUST HAVE, if dev handler supports CDB splitting.
-+ */
-+ bool (*on_sg_tablesize_low) (struct scst_cmd *cmd);
-+
-+ /*
-+ * Called when new device is attaching to the dev handler
-+ * Returns 0 on success, error code otherwise.
-+ *
-+ * OPTIONAL
-+ */
-+ int (*attach) (struct scst_device *dev);
-+
-+ /*
-+ * Called when a device is detaching from the dev handler.
-+ *
-+ * OPTIONAL
-+ */
-+ void (*detach) (struct scst_device *dev);
-+
-+ /*
-+ * Called when new tgt_dev (session) is attaching to the dev handler.
-+ * Returns 0 on success, error code otherwise.
-+ *
-+ * OPTIONAL
-+ */
-+ int (*attach_tgt) (struct scst_tgt_dev *tgt_dev);
-+
-+ /*
-+ * Called when tgt_dev (session) is detaching from the dev handler.
-+ *
-+ * OPTIONAL
-+ */
-+ void (*detach_tgt) (struct scst_tgt_dev *tgt_dev);
-+
-+ /*
-+ * This function adds a virtual device.
-+ *
-+ * If both add_device and del_device callbacks defined, then this
-+ * dev handler supposed to support adding/deleting virtual devices.
-+ * In this case an "mgmt" entry will be created in the sysfs root for
-+ * this handler. The "mgmt" entry will support 2 commands: "add_device"
-+ * and "del_device", for which the corresponding callbacks will be called.
-+ * Also dev handler can define own commands for the "mgmt" entry, see
-+ * mgmt_cmd and mgmt_cmd_help below.
-+ *
-+ * This approach allows uniform devices management to simplify external
-+ * management tools like scstadmin. See README for more details.
-+ *
-+ * Either both add_device and del_device must be defined, or none.
-+ *
-+ * MUST HAVE if virtual devices are supported.
-+ */
-+ ssize_t (*add_device) (const char *device_name, char *params);
-+
-+ /*
-+ * This function deletes a virtual device. See comment for add_device
-+ * above.
-+ *
-+ * MUST HAVE if virtual devices are supported.
-+ */
-+ ssize_t (*del_device) (const char *device_name);
-+
-+ /*
-+ * This function called if not "add_device" or "del_device" command is
-+ * sent to the mgmt entry (see comment for add_device above). In this
-+ * case the command passed to this function as is in a string form.
-+ *
-+ * OPTIONAL.
-+ */
-+ ssize_t (*mgmt_cmd) (char *cmd);
-+
-+ /*
-+ * Name of the dev handler. Must be unique. MUST HAVE.
-+ *
-+ * It's SCST_MAX_NAME + few more bytes to match scst_user expectations.
-+ */
-+ char name[SCST_MAX_NAME + 10];
-+
-+ /*
-+ * Number of threads in this handler's devices' threads pools.
-+ * If 0 - no threads will be created, if <0 - creation of the threads
-+ * pools is prohibited. Also pay attention to threads_pool_type below.
-+ */
-+ int threads_num;
-+
-+ /* Threads pool type. Valid only if threads_num > 0. */
-+ enum scst_dev_type_threads_pool_type threads_pool_type;
-+
-+ /* 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 help string for mgmt_cmd commands */
-+ const char *mgmt_cmd_help;
-+
-+ /* List of parameters for add_device command, if any */
-+ const char *add_device_parameters;
-+
-+ /*
-+ * List of optional, i.e. which could be added by add_attribute command
-+ * and deleted by del_attribute command, sysfs attributes, if any.
-+ * Helpful for scstadmin to work correctly.
-+ */
-+ const char *devt_optional_attributes;
-+
-+ /*
-+ * List of optional, i.e. which could be added by add_device_attribute
-+ * command and deleted by del_device_attribute command, sysfs
-+ * attributes, if any. Helpful for scstadmin to work correctly.
-+ */
-+ const char *dev_optional_attributes;
-+
-+ /* sysfs attributes, if any */
-+ const struct attribute **devt_attrs;
-+
-+ /* sysfs device attributes, if any */
-+ 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, must be inited to 0 by memset() **/
-+
-+ /* list entry in scst_(virtual_)dev_type_list */
-+ struct list_head dev_type_list_entry;
-+
-+ struct kobject devt_kobj; /* main handlers/driver */
-+
-+ /* Number of currently active sysfs mgmt works (scst_sysfs_work_item) */
-+ int devt_active_sysfs_works_count;
-+
-+ /* To wait until devt_kobj released */
-+ struct completion *devt_kobj_release_compl;
-+};
-+
-+/*
-+ * An SCST target, analog of SCSI target port.
-+ */
-+struct scst_tgt {
-+ /* List of remote sessions per target, protected by scst_mutex */
-+ struct list_head sess_list;
-+
-+ /* List entry of targets per template (tgts_list) */
-+ struct list_head tgt_list_entry;
-+
-+ struct scst_tgt_template *tgtt; /* corresponding target template */
-+
-+ struct scst_acg *default_acg; /* default acg for this target */
-+
-+ struct list_head tgt_acg_list; /* target ACG groups */
-+
-+ /*
-+ * Maximum SG table size. Needed here, since different cards on the
-+ * same target template can have different SG table limitations.
-+ */
-+ int sg_tablesize;
-+
-+ /* Used for storage of target driver private stuff */
-+ void *tgt_priv;
-+
-+ /*
-+ * The following fields used to store and retry cmds if target's
-+ * internal queue is full, so the target is unable to accept
-+ * the cmd returning QUEUE FULL.
-+ * They protected by tgt_lock, where necessary.
-+ */
-+ bool retry_timer_active;
-+ struct timer_list retry_timer;
-+ atomic_t finished_cmds;
-+ int retry_cmds;
-+ spinlock_t tgt_lock;
-+ struct list_head retry_cmd_list;
-+
-+ /* Used to wait until session finished to unregister */
-+ wait_queue_head_t unreg_waitQ;
-+
-+ /* Name of the target */
-+ char *tgt_name;
-+
-+ /* User comment to it to let easier distinguish targets */
-+ char *tgt_comment;
-+
-+ uint16_t rel_tgt_id;
-+
-+ /* sysfs release completion */
-+ struct completion *tgt_kobj_release_cmpl;
-+
-+ 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/ */
-+};
-+
-+#ifdef CONFIG_SCST_MEASURE_LATENCY
-+
-+/* Defines extended latency statistics */
-+struct scst_ext_latency_stat {
-+ uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
-+ unsigned int processed_cmds_rd;
-+ uint64_t min_scst_time_rd, min_tgt_time_rd, min_dev_time_rd;
-+ uint64_t max_scst_time_rd, max_tgt_time_rd, max_dev_time_rd;
-+
-+ uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
-+ unsigned int processed_cmds_wr;
-+ uint64_t min_scst_time_wr, min_tgt_time_wr, min_dev_time_wr;
-+ uint64_t max_scst_time_wr, max_tgt_time_wr, max_dev_time_wr;
-+};
-+
-+#define SCST_IO_SIZE_THRESHOLD_SMALL (8*1024)
-+#define SCST_IO_SIZE_THRESHOLD_MEDIUM (32*1024)
-+#define SCST_IO_SIZE_THRESHOLD_LARGE (128*1024)
-+#define SCST_IO_SIZE_THRESHOLD_VERY_LARGE (512*1024)
-+
-+#define SCST_LATENCY_STAT_INDEX_SMALL 0
-+#define SCST_LATENCY_STAT_INDEX_MEDIUM 1
-+#define SCST_LATENCY_STAT_INDEX_LARGE 2
-+#define SCST_LATENCY_STAT_INDEX_VERY_LARGE 3
-+#define SCST_LATENCY_STAT_INDEX_OTHER 4
-+#define SCST_LATENCY_STATS_NUM (SCST_LATENCY_STAT_INDEX_OTHER + 1)
-+
-+#endif /* CONFIG_SCST_MEASURE_LATENCY */
-+
-+struct scst_io_stat_entry {
-+ uint64_t cmd_count;
-+ uint64_t io_byte_count;
-+};
-+
-+/*
-+ * SCST session, analog of SCSI I_T nexus
-+ */
-+struct scst_session {
-+ /*
-+ * Initialization phase, one of SCST_SESS_IPH_* constants, protected by
-+ * sess_list_lock
-+ */
-+ int init_phase;
-+
-+ struct scst_tgt *tgt; /* corresponding target */
-+
-+ /* Used for storage of target driver private stuff */
-+ void *tgt_priv;
-+
-+ /* session's async flags */
-+ unsigned long sess_aflags;
-+
-+ /*
-+ * Hash list for tgt_dev's for this session with size and fn. It isn't
-+ * hlist_entry, because we need ability to go over the list in the
-+ * reverse order. Protected by scst_mutex and suspended activity.
-+ */
-+#define SESS_TGT_DEV_LIST_HASH_SIZE (1 << 5)
-+#define SESS_TGT_DEV_LIST_HASH_FN(val) ((val) & (SESS_TGT_DEV_LIST_HASH_SIZE - 1))
-+ struct list_head sess_tgt_dev_list[SESS_TGT_DEV_LIST_HASH_SIZE];
-+
-+ /*
-+ * List of cmds in this session. Protected by sess_list_lock.
-+ *
-+ * We must always keep commands in the sess list from the
-+ * very beginning, because otherwise they can be missed during
-+ * TM processing.
-+ */
-+ struct list_head sess_cmd_list;
-+
-+ spinlock_t sess_list_lock; /* protects sess_cmd_list, etc */
-+
-+ atomic_t refcnt; /* get/put counter */
-+
-+ /*
-+ * Alive commands for this session. ToDo: make it part of the common
-+ * IO flow control.
-+ */
-+ atomic_t sess_cmd_count;
-+
-+ /* Some statistics. Protected by sess_list_lock. */
-+ struct scst_io_stat_entry io_stats[SCST_DATA_DIR_MAX];
-+
-+ /* Access control for this session and list entry there */
-+ struct scst_acg *acg;
-+
-+ /* Initiator port transport id */
-+ uint8_t *transport_id;
-+
-+ /* List entry for the sessions list inside ACG */
-+ struct list_head acg_sess_list_entry;
-+
-+ struct delayed_work hw_pending_work;
-+
-+ /* Name of attached initiator */
-+ const char *initiator_name;
-+
-+ /* List entry of sessions per target */
-+ struct list_head sess_list_entry;
-+
-+ /* List entry for the list that keeps session, waiting for the init */
-+ struct list_head sess_init_list_entry;
-+
-+ /*
-+ * List entry for the list that keeps session, waiting for the shutdown
-+ */
-+ struct list_head sess_shut_list_entry;
-+
-+ /*
-+ * Lists of deferred during session initialization commands.
-+ * Protected by sess_list_lock.
-+ */
-+ struct list_head init_deferred_cmd_list;
-+ struct list_head init_deferred_mcmd_list;
-+
-+ /*
-+ * Shutdown phase, one of SCST_SESS_SPH_* constants, unprotected.
-+ * Async. relating to init_phase, must be a separate variable, because
-+ * session could be unregistered before async. registration is finished.
-+ */
-+ unsigned long shut_phase;
-+
-+ /* Used if scst_unregister_session() called in wait mode */
-+ struct completion *shutdown_compl;
-+
-+ /* sysfs release completion */
-+ struct completion *sess_kobj_release_cmpl;
-+
-+ unsigned int sess_kobj_ready:1;
-+
-+ struct kobject sess_kobj; /* kobject for this struct */
-+
-+ /*
-+ * Functions and data for user callbacks from scst_register_session()
-+ * and scst_unregister_session()
-+ */
-+ void *reg_sess_data;
-+ void (*init_result_fn) (struct scst_session *sess, void *data,
-+ int result);
-+ void (*unreg_done_fn) (struct scst_session *sess);
-+
-+#ifdef CONFIG_SCST_MEASURE_LATENCY
-+ /*
-+ * Must be the last to allow to work with drivers who don't know
-+ * about this config time option.
-+ */
-+ spinlock_t lat_lock;
-+ uint64_t scst_time, tgt_time, dev_time;
-+ unsigned int processed_cmds;
-+ uint64_t min_scst_time, min_tgt_time, min_dev_time;
-+ uint64_t max_scst_time, max_tgt_time, max_dev_time;
-+ struct scst_ext_latency_stat sess_latency_stat[SCST_LATENCY_STATS_NUM];
-+#endif
-+};
-+
-+/*
-+ * SCST_PR_ABORT_ALL TM function helper structure
-+ */
-+struct scst_pr_abort_all_pending_mgmt_cmds_counter {
-+ /*
-+ * How many there are pending for this cmd SCST_PR_ABORT_ALL TM
-+ * commands.
-+ */
-+ atomic_t pr_abort_pending_cnt;
-+
-+ /* Saved completion routine */
-+ void (*saved_cmd_done) (struct scst_cmd *cmd, int next_state,
-+ enum scst_exec_context pref_context);
-+
-+ /*
-+ * How many there are pending for this cmd SCST_PR_ABORT_ALL TM
-+ * commands, which not yet aborted all affected commands and
-+ * a completion to signal, when it's done.
-+ */
-+ atomic_t pr_aborting_cnt;
-+ struct completion pr_aborting_cmpl;
-+};
-+
-+/*
-+ * Structure to control commands' queuing and threads pool processing the queue
-+ */
-+struct scst_cmd_threads {
-+ spinlock_t cmd_list_lock;
-+ struct list_head active_cmd_list; /* commands queue */
-+ wait_queue_head_t cmd_list_waitQ;
-+
-+ struct io_context *io_context; /* IO context of the threads pool */
-+ int io_context_refcnt;
-+
-+ bool io_context_ready;
-+
-+ /* io_context_mutex protects io_context and io_context_refcnt. */
-+ struct mutex io_context_mutex;
-+
-+ int nr_threads; /* number of processing threads */
-+ struct list_head threads_list; /* processing threads */
-+
-+ struct list_head lists_list_entry;
-+};
-+
-+/*
-+ * Used to execute cmd's in order of arrival, honoring SCSI task attributes
-+ */
-+struct scst_order_data {
-+ /*
-+ * Protected by sn_lock, except expected_sn, which is protected by
-+ * itself. Curr_sn must have the same size as expected_sn to
-+ * overflow simultaneously.
-+ */
-+ int def_cmd_count;
-+ spinlock_t sn_lock;
-+ unsigned int expected_sn;
-+ unsigned int curr_sn;
-+ int hq_cmd_count;
-+ struct list_head deferred_cmd_list;
-+ struct list_head skipped_sn_list;
-+
-+ /*
-+ * Set if the prev cmd was ORDERED. Size and, hence, alignment must
-+ * allow unprotected modifications independently to the neighbour fields.
-+ */
-+ unsigned long prev_cmd_ordered;
-+
-+ int num_free_sn_slots; /* if it's <0, then all slots are busy */
-+ atomic_t *cur_sn_slot;
-+ atomic_t sn_slots[15];
-+};
-+
-+/*
-+ * SCST command, analog of I_T_L_Q nexus or task
-+ */
-+struct scst_cmd {
-+ /* List entry for below *_cmd_threads */
-+ struct list_head cmd_list_entry;
-+
-+ /* Pointer to lists of commands with the lock */
-+ struct scst_cmd_threads *cmd_threads;
-+
-+ atomic_t cmd_ref;
-+
-+ struct scst_session *sess; /* corresponding session */
-+
-+ atomic_t *cpu_cmd_counter;
-+
-+ /* Cmd state, one of SCST_CMD_STATE_* constants */
-+ int state;
-+
-+ /*************************************************************
-+ ** Cmd's flags
-+ *************************************************************/
-+
-+ /*
-+ * Set if expected_sn should be incremented, i.e. cmd was sent
-+ * for execution
-+ */
-+ unsigned int sent_for_exec:1;
-+
-+ /* Set if the cmd's action is completed */
-+ unsigned int completed:1;
-+
-+ /* Set if we should ignore Unit Attention in scst_check_sense() */
-+ unsigned int ua_ignore:1;
-+
-+ /* Set if cmd is being processed in atomic context */
-+ unsigned int atomic:1;
-+
-+ /* Set if this command was sent in double UA possible state */
-+ unsigned int double_ua_possible:1;
-+
-+ /* Set if this command contains status */
-+ unsigned int is_send_status:1;
-+
-+ /* Set if cmd is being retried */
-+ unsigned int retry:1;
-+
-+ /* Set if cmd is internally generated */
-+ unsigned int internal:1;
-+
-+ /* Set if the device was blocked by scst_check_blocked_dev() */
-+ unsigned int unblock_dev:1;
-+
-+ /* Set if this cmd incremented dev->pr_readers_count */
-+ unsigned int dec_pr_readers_count_needed:1;
-+
-+ /* Set if scst_dec_on_dev_cmd() call is needed on the cmd's finish */
-+ unsigned int dec_on_dev_needed:1;
-+
-+ /* Set if cmd is queued as hw pending */
-+ unsigned int cmd_hw_pending:1;
-+
-+ /*
-+ * Set, if for this cmd required to not have any IO or FS calls on
-+ * memory buffers allocations, at least for READ and WRITE commands.
-+ * Needed for cases like file systems mounted over scst_local's
-+ * devices.
-+ */
-+ unsigned noio_mem_alloc:1;
-+
-+ /*
-+ * Set if the target driver wants to alloc data buffers on its own.
-+ * In this case alloc_data_buf() must be provided in the target driver
-+ * template.
-+ */
-+ unsigned int tgt_need_alloc_data_buf:1;
-+
-+ /*
-+ * Set by SCST if the custom data buffer allocation by the target driver
-+ * succeeded.
-+ */
-+ unsigned int tgt_data_buf_alloced:1;
-+
-+ /* Set if custom data buffer allocated by dev handler */
-+ unsigned int dh_data_buf_alloced:1;
-+
-+ /* Set if the target driver called scst_set_expected() */
-+ unsigned int expected_values_set:1;
-+
-+ /*
-+ * Set if the SG buffer was modified by scst_adjust_sg()
-+ */
-+ unsigned int sg_buff_modified:1;
-+
-+ /*
-+ * Set if cmd buffer was vmallocated and copied from more
-+ * then one sg chunk
-+ */
-+ unsigned int sg_buff_vmallocated:1;
-+
-+ /*
-+ * Set if scst_cmd_init_stage1_done() called and the target
-+ * want that preprocessing_done() will be called
-+ */
-+ unsigned int preprocessing_only:1;
-+
-+ /* Set if cmd's SN was set */
-+ unsigned int sn_set:1;
-+
-+ /* Set if hq_cmd_count was incremented */
-+ unsigned int hq_cmd_inced:1;
-+
-+ /*
-+ * Set if scst_cmd_init_stage1_done() called and the target wants
-+ * that the SN for the cmd won't be assigned until scst_restart_cmd()
-+ */
-+ unsigned int set_sn_on_restart_cmd:1;
-+
-+ /* Set if the cmd's must not use sgv cache for data buffer */
-+ unsigned int no_sgv:1;
-+
-+ /*
-+ * Set if target driver may need to call dma_sync_sg() or similar
-+ * function before transferring cmd' data to the target device
-+ * via DMA.
-+ */
-+ unsigned int may_need_dma_sync:1;
-+
-+ /* Set if the cmd was done or aborted out of its SN */
-+ unsigned int out_of_sn:1;
-+
-+ /* Set if increment expected_sn in cmd->scst_cmd_done() */
-+ unsigned int inc_expected_sn_on_done:1;
-+
-+ /* Set if tgt_sn field is valid */
-+ unsigned int tgt_sn_set:1;
-+
-+ /* Set if any direction residual is possible */
-+ unsigned int resid_possible:1;
-+
-+ /* Set if cmd is done */
-+ unsigned int done:1;
-+
-+ /*
-+ * Set if cmd is finished. Used under sess_list_lock to sync
-+ * between scst_finish_cmd() and scst_abort_cmd()
-+ */
-+ unsigned int finished:1;
-+
-+ /*
-+ * Set if scst_check_local_events() can be called more than once. Set by
-+ * scst_pre_check_local_events().
-+ */
-+ unsigned int check_local_events_once_done:1;
-+
-+#ifdef CONFIG_SCST_DEBUG_TM
-+ /* Set if the cmd was delayed by task management debugging code */
-+ unsigned int tm_dbg_delayed:1;
-+
-+ /* Set if the cmd must be ignored by task management debugging code */
-+ unsigned int tm_dbg_immut:1;
-+#endif
-+
-+ /**************************************************************/
-+
-+ /* cmd's async flags */
-+ unsigned long cmd_flags;
-+
-+ /* Keeps status of cmd's status/data delivery to remote initiator */
-+ int delivery_status;
-+
-+ struct scst_tgt_template *tgtt; /* to save extra dereferences */
-+ struct scst_tgt *tgt; /* to save extra dereferences */
-+ struct scst_device *dev; /* to save extra dereferences */
-+
-+ /* corresponding I_T_L device for this cmd */
-+ struct scst_tgt_dev *tgt_dev;
-+
-+ struct scst_order_data *cur_order_data; /* to save extra dereferences */
-+
-+ uint64_t lun; /* LUN for this cmd */
-+
-+ unsigned long start_time;
-+
-+ /* List entry for tgt_dev's SN related lists */
-+ struct list_head sn_cmd_list_entry;
-+
-+ /* Cmd's serial number, used to execute cmd's in order of arrival */
-+ unsigned int sn;
-+
-+ /* The corresponding sn_slot in tgt_dev->sn_slots */
-+ atomic_t *sn_slot;
-+
-+ /* List entry for sess's sess_cmd_list */
-+ struct list_head sess_cmd_list_entry;
-+
-+ /*
-+ * Used to found the cmd by scst_find_cmd_by_tag(). Set by the
-+ * target driver on the cmd's initialization time
-+ */
-+ uint64_t tag;
-+
-+ uint32_t tgt_sn; /* SN set by target driver (for TM purposes) */
-+
-+ uint8_t *cdb; /* Pointer on CDB. Points on cdb_buf for small CDBs. */
-+ unsigned short cdb_len;
-+ uint8_t cdb_buf[SCST_MAX_CDB_SIZE];
-+
-+ enum scst_cdb_flags op_flags;
-+ const char *op_name;
-+
-+ enum scst_cmd_queue_type queue_type;
-+
-+ int timeout; /* CDB execution timeout in seconds */
-+ int retries; /* Amount of retries that will be done by SCSI mid-level */
-+
-+ /* SCSI data direction, one of SCST_DATA_* constants */
-+ scst_data_direction data_direction;
-+
-+ /* Remote initiator supplied values, if any */
-+ scst_data_direction expected_data_direction;
-+ int expected_transfer_len;
-+ int expected_out_transfer_len; /* for bidi writes */
-+
-+ /*
-+ * Cmd data length. Could be different from bufflen for commands like
-+ * VERIFY, which transfer different amount of data (if any), than
-+ * processed.
-+ */
-+ int data_len;
-+
-+ /* Completion routine */
-+ void (*scst_cmd_done) (struct scst_cmd *cmd, int next_state,
-+ enum scst_exec_context pref_context);
-+
-+ struct sgv_pool_obj *sgv; /* sgv object */
-+ int bufflen; /* cmd buffer length */
-+ struct scatterlist *sg; /* cmd data buffer SG vector */
-+ int sg_cnt; /* SG segments count */
-+
-+ /*
-+ * Response data length in data buffer. Must not be set
-+ * directly, use scst_set_resp_data_len() for that.
-+ */
-+ int resp_data_len;
-+
-+ /*
-+ * Response data length adjusted on residual, i.e.
-+ * min(expected_len, resp_len), if expected len set.
-+ */
-+ int adjusted_resp_data_len;
-+
-+ /*
-+ * Data length to write, i.e. transfer from the initiator. Might be
-+ * different from (out_)bufflen, if the initiator asked too big or too
-+ * small expected(_out_)transfer_len.
-+ */
-+ int write_len;
-+
-+ /*
-+ * Write sg and sg_cnt to point out either on sg/sg_cnt, or on
-+ * out_sg/out_sg_cnt.
-+ */
-+ struct scatterlist **write_sg;
-+ int *write_sg_cnt;
-+
-+ /* scst_get_sg_buf_[first,next]() support */
-+ struct scatterlist *get_sg_buf_cur_sg_entry;
-+ int get_sg_buf_entry_num;
-+
-+ /* Bidirectional transfers support */
-+ int out_bufflen; /* WRITE buffer length */
-+ struct sgv_pool_obj *out_sgv; /* WRITE sgv object */
-+ struct scatterlist *out_sg; /* WRITE data buffer SG vector */
-+ int out_sg_cnt; /* WRITE SG segments count */
-+
-+ /*
-+ * Used if both target driver and dev handler request own memory
-+ * allocation. In other cases, both are equal to sg and sg_cnt
-+ * correspondingly.
-+ *
-+ * If target driver requests own memory allocations, it MUST use
-+ * functions scst_cmd_get_tgt_sg*() to get sg and sg_cnt! Otherwise,
-+ * it may use functions scst_cmd_get_sg*().
-+ */
-+ struct scatterlist *tgt_sg;
-+ int tgt_sg_cnt;
-+ struct scatterlist *tgt_out_sg; /* bidirectional */
-+ int tgt_out_sg_cnt; /* bidirectional */
-+
-+ /*
-+ * The status fields in case of errors must be set using
-+ * scst_set_cmd_error_status()!
-+ */
-+ uint8_t status; /* status byte from target device */
-+ uint8_t msg_status; /* return status from host adapter itself */
-+ uint8_t host_status; /* set by low-level driver to indicate status */
-+ uint8_t driver_status; /* set by mid-level */
-+
-+ uint8_t *sense; /* pointer to sense buffer */
-+ unsigned short sense_valid_len; /* length of valid sense data */
-+ unsigned short sense_buflen; /* length of the sense buffer, if any */
-+
-+ /* Start time when cmd was sent to rdy_to_xfer() or xmit_response() */
-+ unsigned long hw_pending_start;
-+
-+ /* Used for storage of target driver private stuff */
-+ void *tgt_priv;
-+
-+ /* Used for storage of dev handler private stuff */
-+ void *dh_priv;
-+
-+ /* Used to restore sg if it was modified by scst_adjust_sg() */
-+ struct scatterlist *orig_sg;
-+ int *p_orig_sg_cnt;
-+ int orig_sg_cnt, orig_sg_entry, orig_entry_len;
-+
-+ /* Used to retry commands in case of double UA */
-+ int dbl_ua_orig_resp_data_len, dbl_ua_orig_data_direction;
-+
-+ /*
-+ * List of the corresponding mgmt cmds, if any. Protected by
-+ * sess_list_lock.
-+ */
-+ struct list_head mgmt_cmd_list;
-+
-+ /* List entry for dev's blocked_cmd_list */
-+ struct list_head blocked_cmd_list_entry;
-+
-+ /* Counter of the corresponding SCST_PR_ABORT_ALL TM commands */
-+ struct scst_pr_abort_all_pending_mgmt_cmds_counter *pr_abort_counter;
-+
-+ struct scst_cmd *orig_cmd; /* Used to issue REQUEST SENSE */
-+
-+#ifdef CONFIG_SCST_MEASURE_LATENCY
-+ /*
-+ * Must be the last to allow to work with drivers who don't know
-+ * about this config time option.
-+ */
-+ uint64_t start, curr_start, parse_time, alloc_buf_time;
-+ uint64_t restart_waiting_time, rdy_to_xfer_time;
-+ uint64_t pre_exec_time, exec_time, dev_done_time;
-+ uint64_t xmit_time, tgt_on_free_time, dev_on_free_time;
-+#endif
-+};
-+
-+/*
-+ * Parameters for SCST management commands
-+ */
-+struct scst_rx_mgmt_params {
-+ int fn;
-+ uint64_t tag;
-+ const uint8_t *lun;
-+ int lun_len;
-+ uint32_t cmd_sn;
-+ int atomic;
-+ void *tgt_priv;
-+ unsigned char tag_set;
-+ unsigned char lun_set;
-+ unsigned char cmd_sn_set;
-+};
-+
-+/*
-+ * A stub structure to link an management command and affected regular commands
-+ */
-+struct scst_mgmt_cmd_stub {
-+ struct scst_mgmt_cmd *mcmd;
-+
-+ /* List entry in cmd->mgmt_cmd_list */
-+ struct list_head cmd_mgmt_cmd_list_entry;
-+
-+ /* Set if the cmd was counted in mcmd->cmd_done_wait_count */
-+ unsigned int done_counted:1;
-+
-+ /* Set if the cmd was counted in mcmd->cmd_finish_wait_count */
-+ unsigned int finish_counted:1;
-+};
-+
-+/*
-+ * SCST task management structure
-+ */
-+struct scst_mgmt_cmd {
-+ /* List entry for *_mgmt_cmd_list */
-+ struct list_head mgmt_cmd_list_entry;
-+
-+ struct scst_session *sess;
-+
-+ atomic_t *cpu_cmd_counter;
-+
-+ /* Mgmt cmd state, one of SCST_MCMD_STATE_* constants */
-+ int state;
-+
-+ int fn; /* task management function */
-+
-+ /* Set if device(s) should be unblocked after mcmd's finish */
-+ unsigned int needs_unblocking:1;
-+ unsigned int lun_set:1; /* set, if lun field is valid */
-+ unsigned int cmd_sn_set:1; /* set, if cmd_sn field is valid */
-+
-+ /*
-+ * Number of commands to finish before sending response,
-+ * protected by scst_mcmd_lock
-+ */
-+ int cmd_finish_wait_count;
-+
-+ /*
-+ * Number of commands to complete (done) before resetting reservation,
-+ * protected by scst_mcmd_lock
-+ */
-+ int cmd_done_wait_count;
-+
-+ /* Number of completed commands, protected by scst_mcmd_lock */
-+ int completed_cmd_count;
-+
-+ uint64_t lun; /* LUN for this mgmt cmd */
-+ /* or (and for iSCSI) */
-+ uint64_t tag; /* tag of the corresponding cmd */
-+
-+ uint32_t cmd_sn; /* affected command's highest SN */
-+
-+ /* corresponding cmd (to be aborted, found by tag) */
-+ struct scst_cmd *cmd_to_abort;
-+
-+ /* corresponding device for this mgmt cmd (found by lun) */
-+ struct scst_tgt_dev *mcmd_tgt_dev;
-+
-+ /* completion status, one of the SCST_MGMT_STATUS_* constants */
-+ int status;
-+
-+ /* Used for storage of target driver private stuff or origin PR cmd */
-+ union {
-+ void *tgt_priv;
-+ struct scst_cmd *origin_pr_cmd;
-+ };
-+};
-+
-+/*
-+ * Persistent reservations registrant
-+ */
-+struct scst_dev_registrant {
-+ uint8_t *transport_id;
-+ uint16_t rel_tgt_id;
-+ __be64 key;
-+
-+ /* tgt_dev (I_T nexus) for this registrant, if any */
-+ struct scst_tgt_dev *tgt_dev;
-+
-+ /* List entry for dev_registrants_list */
-+ struct list_head dev_registrants_list_entry;
-+
-+ /* 2 auxiliary fields used to rollback changes for errors, etc. */
-+ struct list_head aux_list_entry;
-+ __be64 rollback_key;
-+};
-+
-+/*
-+ * SCST device
-+ */
-+struct scst_device {
-+ unsigned short type; /* SCSI type of the device */
-+
-+ /*************************************************************
-+ ** Dev's flags. Updates serialized by dev_lock or suspended
-+ ** activity
-+ *************************************************************/
-+
-+ /* Set if dev is RESERVED */
-+ unsigned short dev_reserved:1;
-+
-+ /* Set if double reset UA is possible */
-+ unsigned short dev_double_ua_possible:1;
-+
-+ /* If set, dev is read only */
-+ unsigned short rd_only:1;
-+
-+ /* Set, if a strictly serialized cmd is waiting blocked */
-+ unsigned short strictly_serialized_cmd_waiting:1;
-+
-+ /*
-+ * Set, if this device is being unregistered. Useful to let sysfs
-+ * attributes know when they should exit immediatelly to prevent
-+ * possible deadlocks with their device unregistration waiting for
-+ * their kobj last put.
-+ */
-+ unsigned short dev_unregistering:1;
-+
-+ /**************************************************************/
-+
-+ /*************************************************************
-+ ** Dev's control mode page related values. Updates serialized
-+ ** by scst_block_dev(). Modified independently to the above and
-+ ** below fields, hence the alignment.
-+ *************************************************************/
-+
-+ unsigned int queue_alg:4 __attribute__((aligned(sizeof(long))));
-+ unsigned int tst:3;
-+ unsigned int tas:1;
-+ unsigned int swp:1;
-+ unsigned int d_sense:1;
-+
-+ /*
-+ * Set if device implements own ordered commands management. If not set
-+ * and queue_alg is SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER,
-+ * expected_sn will be incremented only after commands finished.
-+ */
-+ unsigned int has_own_order_mgmt:1;
-+
-+ /**************************************************************/
-+
-+ /* How many cmds alive on this dev */
-+ atomic_t dev_cmd_count;
-+
-+ spinlock_t dev_lock; /* device lock */
-+
-+ /*
-+ * How many times device was blocked for new cmds execution.
-+ * Protected by dev_lock.
-+ */
-+ int block_count;
-+
-+ /*
-+ * How many there are "on_dev" commands, i.e. ones who passed
-+ * scst_check_blocked_dev(). Protected by dev_lock.
-+ */
-+ int on_dev_cmd_count;
-+
-+ /*
-+ * How many threads are checking commands for PR allowance.
-+ * Protected by dev_lock.
-+ */
-+ int pr_readers_count;
-+
-+ /*
-+ * Set if dev is persistently reserved. Protected by dev_pr_mutex.
-+ * Modified independently to the above field, hence the alignment.
-+ */
-+ unsigned int pr_is_set:1 __attribute__((aligned(sizeof(long))));
-+
-+ /*
-+ * Set if there is a thread changing or going to change PR state(s).
-+ * Protected by dev_pr_mutex.
-+ */
-+ unsigned int pr_writer_active:1;
-+
-+ struct scst_dev_type *handler; /* corresponding dev handler */
-+
-+ /* Used for storage of dev handler private stuff */
-+ void *dh_priv;
-+
-+ /* Corresponding real SCSI device, could be NULL for virtual devices */
-+ struct scsi_device *scsi_dev;
-+
-+ /* List of commands with lock, if dedicated threads are used */
-+ struct scst_cmd_threads dev_cmd_threads;
-+
-+ /* Memory limits for this device */
-+ struct scst_mem_lim dev_mem_lim;
-+
-+ /*************************************************************
-+ ** Persistent reservation fields. Protected by dev_pr_mutex.
-+ *************************************************************/
-+
-+ /*
-+ * True if persist through power loss is activated. Modified
-+ * independently to the above field, hence the alignment.
-+ */
-+ unsigned short pr_aptpl:1 __attribute__((aligned(sizeof(long))));
-+
-+ /* Persistent reservation type */
-+ uint8_t pr_type;
-+
-+ /* Persistent reservation scope */
-+ uint8_t pr_scope;
-+
-+ /* Mutex to protect PR operations */
-+ struct mutex dev_pr_mutex;
-+
-+ /* Persistent reservation generation value */
-+ uint32_t pr_generation;
-+
-+ /* Reference to registrant - persistent reservation holder */
-+ struct scst_dev_registrant *pr_holder;
-+
-+ /* List of dev's registrants */
-+ struct list_head dev_registrants_list;
-+
-+ /*
-+ * Count of connected tgt_devs from transports, which don't support
-+ * PRs, i.e. don't have get_initiator_port_transport_id(). Protected
-+ * by scst_mutex.
-+ */
-+ int not_pr_supporting_tgt_devs_num;
-+
-+ struct scst_order_data dev_order_data;
-+
-+ /* Persist through power loss files */
-+ char *pr_file_name;
-+ char *pr_file_name1;
-+
-+ /**************************************************************/
-+
-+ /* List of blocked commands, protected by dev_lock. */
-+ struct list_head blocked_cmd_list;
-+
-+ /* A list entry used during TM, protected by scst_mutex */
-+ struct list_head tm_dev_list_entry;
-+
-+ int virt_id; /* virtual device internal ID */
-+
-+ /* Pointer to virtual device name, for convenience only */
-+ char *virt_name;
-+
-+ struct list_head dev_list_entry; /* list entry in global devices list */
-+
-+ /*
-+ * List of tgt_dev's, one per session, protected by scst_mutex or
-+ * dev_lock for reads and both for writes
-+ */
-+ struct list_head dev_tgt_dev_list;
-+
-+ /* List of acg_dev's, one per acg, protected by scst_mutex */
-+ struct list_head dev_acg_dev_list;
-+
-+ /* Number of threads in the device's threads pools */
-+ int threads_num;
-+
-+ /* Threads pool type of the device. Valid only if threads_num > 0. */
-+ enum scst_dev_type_threads_pool_type threads_pool_type;
-+
-+ /* sysfs release completion */
-+ struct completion *dev_kobj_release_cmpl;
-+
-+ 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;
-+};
-+
-+/*
-+ * Used to store threads local tgt_dev specific data
-+ */
-+struct scst_thr_data_hdr {
-+ /* List entry in tgt_dev->thr_data_list */
-+ struct list_head thr_data_list_entry;
-+ struct task_struct *owner_thr; /* the owner thread */
-+ atomic_t ref;
-+ /* Function that will be called on the tgt_dev destruction */
-+ void (*free_fn) (struct scst_thr_data_hdr *data);
-+};
-+
-+/*
-+ * Used to clearly dispose async io_context
-+ */
-+struct scst_async_io_context_keeper {
-+ struct kref aic_keeper_kref;
-+ bool aic_ready;
-+ struct io_context *aic;
-+ struct task_struct *aic_keeper_thr;
-+ wait_queue_head_t aic_keeper_waitQ;
-+};
-+
-+/*
-+ * Used to store per-session specific device information, analog of
-+ * SCSI I_T_L nexus.
-+ */
-+struct scst_tgt_dev {
-+ /* List entry in sess->sess_tgt_dev_list */
-+ struct list_head sess_tgt_dev_list_entry;
-+
-+ struct scst_device *dev; /* to save extra dereferences */
-+ uint64_t lun; /* to save extra dereferences */
-+
-+ gfp_t gfp_mask;
-+ struct sgv_pool *pool;
-+ int max_sg_cnt;
-+
-+ /*
-+ * Tgt_dev's async flags. Modified independently to the neighbour
-+ * fields.
-+ */
-+ unsigned long tgt_dev_flags;
-+
-+ /* Used for storage of dev handler private stuff */
-+ void *dh_priv;
-+
-+ /* How many cmds alive on this dev in this session */
-+ atomic_t tgt_dev_cmd_count;
-+
-+ struct scst_order_data *curr_order_data;
-+ struct scst_order_data tgt_dev_order_data;
-+
-+ /* List of scst_thr_data_hdr and lock */
-+ spinlock_t thr_data_lock;
-+ struct list_head thr_data_list;
-+
-+ /* Pointer to lists of commands with the lock */
-+ struct scst_cmd_threads *active_cmd_threads;
-+
-+ /* Union to save some CPU cache footprint */
-+ union {
-+ struct {
-+ /* Copy to save fast path dereference */
-+ struct io_context *async_io_context;
-+
-+ struct scst_async_io_context_keeper *aic_keeper;
-+ };
-+
-+ /* Lists of commands with lock, if dedicated threads are used */
-+ struct scst_cmd_threads tgt_dev_cmd_threads;
-+ };
-+
-+ spinlock_t tgt_dev_lock; /* per-session device lock */
-+
-+ /* List of UA's for this device, protected by tgt_dev_lock */
-+ struct list_head UA_list;
-+
-+ struct scst_session *sess; /* corresponding session */
-+ struct scst_acg_dev *acg_dev; /* corresponding acg_dev */
-+
-+ /* Reference to registrant to find quicker */
-+ struct scst_dev_registrant *registrant;
-+
-+ /* List entry in dev->dev_tgt_dev_list */
-+ struct list_head dev_tgt_dev_list_entry;
-+
-+ /* Internal tmp list entry */
-+ struct list_head extra_tgt_dev_list_entry;
-+
-+ /* Set if INQUIRY DATA HAS CHANGED UA is needed */
-+ unsigned int inq_changed_ua_needed:1;
-+
-+ /*
-+ * Stored Unit Attention sense and its length for possible
-+ * subsequent REQUEST SENSE. Both protected by tgt_dev_lock.
-+ */
-+ unsigned short tgt_dev_valid_sense_len;
-+ uint8_t tgt_dev_sense[SCST_SENSE_BUFFERSIZE];
-+
-+ /* sysfs release completion */
-+ struct completion *tgt_dev_kobj_release_cmpl;
-+
-+ struct kobject tgt_dev_kobj; /* kobject for this struct */
-+
-+#ifdef CONFIG_SCST_MEASURE_LATENCY
-+ /*
-+ * Must be the last to allow to work with drivers who don't know
-+ * about this config time option.
-+ *
-+ * Protected by sess->lat_lock.
-+ */
-+ uint64_t scst_time, tgt_time, dev_time;
-+ unsigned int processed_cmds;
-+ struct scst_ext_latency_stat dev_latency_stat[SCST_LATENCY_STATS_NUM];
-+#endif
-+};
-+
-+/*
-+ * Used to store ACG-specific device information, like LUN
-+ */
-+struct scst_acg_dev {
-+ struct scst_device *dev; /* corresponding device */
-+
-+ uint64_t lun; /* device's LUN in this acg */
-+
-+ /* If set, the corresponding LU is read only */
-+ unsigned int rd_only: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 */
-+ struct list_head acg_dev_list_entry;
-+
-+ /* kobject for this structure */
-+ struct kobject acg_dev_kobj;
-+
-+ /* sysfs release completion */
-+ struct completion *acg_dev_kobj_release_cmpl;
-+
-+ /* Name of the link to the corresponding LUN */
-+ char acg_dev_link_name[20];
-+};
-+
-+/*
-+ * ACG - access control group. Used to store group related
-+ * control information.
-+ */
-+struct scst_acg {
-+ /* Owner target */
-+ struct scst_tgt *tgt;
-+
-+ /* List of acg_dev's in this acg, protected by scst_mutex */
-+ struct list_head acg_dev_list;
-+
-+ /* List of attached sessions, protected by scst_mutex */
-+ struct list_head acg_sess_list;
-+
-+ /* List of attached acn's, protected by scst_mutex */
-+ struct list_head acn_list;
-+
-+ /* List entry in acg_lists */
-+ struct list_head acg_list_entry;
-+
-+ /* Name of this acg */
-+ const char *acg_name;
-+
-+ /* Type of I/O initiators grouping */
-+ int acg_io_grouping_type;
-+
-+ /* CPU affinity for threads in this ACG */
-+ cpumask_t acg_cpu_mask;
-+
-+ unsigned int tgt_acg:1;
-+
-+ /* sysfs release completion */
-+ struct completion *acg_kobj_release_cmpl;
-+
-+ /* kobject for this structure */
-+ struct kobject acg_kobj;
-+
-+ struct kobject *luns_kobj;
-+ struct kobject *initiators_kobj;
-+
-+ enum scst_lun_addr_method addr_method;
-+};
-+
-+/*
-+ * ACN - access control name. Used to store names, by which
-+ * incoming sessions will be assigned to appropriate ACG.
-+ */
-+struct scst_acn {
-+ struct scst_acg *acg; /* owner ACG */
-+
-+ const char *name; /* initiator's name */
-+
-+ /* List entry in acg->acn_list */
-+ struct list_head acn_list_entry;
-+
-+ /* sysfs file attributes */
-+ struct kobj_attribute *acn_attr;
-+};
-+
-+/**
-+ * struct scst_dev_group - A group of SCST devices (struct scst_device).
-+ *
-+ * Each device is member of zero or one device groups. With each device group
-+ * there are zero or more target groups associated.
-+ */
-+struct scst_dev_group {
-+ char *name;
-+ struct list_head entry;
-+ struct list_head dev_list;
-+ struct list_head tg_list;
-+ struct kobject kobj;
-+ struct kobject *dev_kobj;
-+ struct kobject *tg_kobj;
-+};
-+
-+/**
-+ * struct scst_dg_dev - A node in scst_dev_group.dev_list.
-+ */
-+struct scst_dg_dev {
-+ struct list_head entry;
-+ struct scst_device *dev;
-+};
-+
-+/**
-+ * struct scst_target_group - A group of SCSI targets (struct scst_tgt).
-+ *
-+ * Such a group is either a primary target port group or a secondary
-+ * port group. See also SPC-4 for more information.
-+ */
-+struct scst_target_group {
-+ struct scst_dev_group *dg;
-+ char *name;
-+ uint16_t group_id;
-+ enum scst_tg_state state;
-+ bool preferred;
-+ struct list_head entry;
-+ struct list_head tgt_list;
-+ struct kobject kobj;
-+};
-+
-+/**
-+ * struct scst_tg_tgt - A node in scst_target_group.tgt_list.
-+ *
-+ * Such a node can either represent a local storage target (struct scst_tgt)
-+ * or a storage target on another system running SCST. In the former case tgt
-+ * != NULL and rel_tgt_id is ignored. In the latter case tgt == NULL and
-+ * rel_tgt_id is relevant.
-+ */
-+struct scst_tg_tgt {
-+ struct list_head entry;
-+ struct scst_target_group *tg;
-+ struct kobject kobj;
-+ struct scst_tgt *tgt;
-+ char *name;
-+ uint16_t rel_tgt_id;
-+};
-+
-+/*
-+ * Used to store per-session UNIT ATTENTIONs
-+ */
-+struct scst_tgt_dev_UA {
-+ /* List entry in tgt_dev->UA_list */
-+ struct list_head UA_list_entry;
-+
-+ /* Set if UA is global for session */
-+ unsigned short global_UA:1;
-+
-+ /* Unit Attention valid sense len */
-+ unsigned short UA_valid_sense_len;
-+ /* Unit Attention sense buf */
-+ uint8_t UA_sense_buffer[SCST_SENSE_BUFFERSIZE];
-+};
-+
-+/* Used to deliver AENs */
-+struct scst_aen {
-+ int event_fn; /* AEN fn */
-+
-+ struct scst_session *sess; /* corresponding session */
-+ __be64 lun; /* corresponding LUN in SCSI form */
-+
-+ union {
-+ /* SCSI AEN data */
-+ struct {
-+ int aen_sense_len;
-+ uint8_t aen_sense[SCST_STANDARD_SENSE_LEN];
-+ };
-+ };
-+
-+ /* Keeps status of AEN's delivery to remote initiator */
-+ int delivery_status;
-+};
-+
-+#ifndef smp_mb__after_set_bit
-+/* There is no smp_mb__after_set_bit() in the kernel */
-+#define smp_mb__after_set_bit() smp_mb()
-+#endif
-+
-+/*
-+ * Registers target template.
-+ * Returns 0 on success or appropriate error code otherwise.
-+ */
-+int __scst_register_target_template(struct scst_tgt_template *vtt,
-+ const char *version);
-+static inline int scst_register_target_template(struct scst_tgt_template *vtt)
-+{
-+ return __scst_register_target_template(vtt, SCST_INTERFACE_VERSION);
-+}
-+
-+/*
-+ * Registers target template, non-GPL version.
-+ * Returns 0 on success or appropriate error code otherwise.
-+ *
-+ * Note: *vtt must be static!
-+ */
-+int __scst_register_target_template_non_gpl(struct scst_tgt_template *vtt,
-+ const char *version);
-+static inline int scst_register_target_template_non_gpl(
-+ struct scst_tgt_template *vtt)
-+{
-+ return __scst_register_target_template_non_gpl(vtt,
-+ SCST_INTERFACE_VERSION);
-+}
-+
-+void scst_unregister_target_template(struct scst_tgt_template *vtt);
-+
-+struct scst_tgt *scst_register_target(struct scst_tgt_template *vtt,
-+ const char *target_name);
-+void scst_unregister_target(struct scst_tgt *tgt);
-+
-+struct scst_session *scst_register_session(struct scst_tgt *tgt, int atomic,
-+ const char *initiator_name, void *tgt_priv, void *result_fn_data,
-+ void (*result_fn) (struct scst_session *sess, void *data, int result));
-+struct scst_session *scst_register_session_non_gpl(struct scst_tgt *tgt,
-+ const char *initiator_name, void *tgt_priv);
-+void scst_unregister_session(struct scst_session *sess, int wait,
-+ void (*unreg_done_fn) (struct scst_session *sess));
-+void scst_unregister_session_non_gpl(struct scst_session *sess);
-+
-+int __scst_register_dev_driver(struct scst_dev_type *dev_type,
-+ const char *version);
-+static inline int scst_register_dev_driver(struct scst_dev_type *dev_type)
-+{
-+ return __scst_register_dev_driver(dev_type, SCST_INTERFACE_VERSION);
-+}
-+void scst_unregister_dev_driver(struct scst_dev_type *dev_type);
-+
-+int __scst_register_virtual_dev_driver(struct scst_dev_type *dev_type,
-+ const char *version);
-+/*
-+ * Registers dev handler driver for virtual devices (eg VDISK).
-+ * Returns 0 on success or appropriate error code otherwise.
-+ */
-+static inline int scst_register_virtual_dev_driver(
-+ struct scst_dev_type *dev_type)
-+{
-+ return __scst_register_virtual_dev_driver(dev_type,
-+ SCST_INTERFACE_VERSION);
-+}
-+
-+void scst_unregister_virtual_dev_driver(struct scst_dev_type *dev_type);
-+
-+bool scst_initiator_has_luns(struct scst_tgt *tgt, const char *initiator_name);
-+
-+struct scst_cmd *scst_rx_cmd(struct scst_session *sess,
-+ const uint8_t *lun, int lun_len, const uint8_t *cdb,
-+ unsigned int cdb_len, int atomic);
-+void scst_cmd_init_done(struct scst_cmd *cmd,
-+ enum scst_exec_context pref_context);
-+
-+/*
-+ * Notifies SCST that the driver finished the first stage of the command
-+ * initialization, and the command is ready for execution, but after
-+ * SCST done the command's preprocessing preprocessing_done() function
-+ * should be called. The second argument sets preferred command execution
-+ * context. See SCST_CONTEXT_* constants for details.
-+ *
-+ * See comment for scst_cmd_init_done() for the serialization requirements.
-+ */
-+static inline void scst_cmd_init_stage1_done(struct scst_cmd *cmd,
-+ enum scst_exec_context pref_context, int set_sn)
-+{
-+ cmd->preprocessing_only = 1;
-+ cmd->set_sn_on_restart_cmd = !set_sn;
-+ scst_cmd_init_done(cmd, pref_context);
-+}
-+
-+void scst_restart_cmd(struct scst_cmd *cmd, int status,
-+ enum scst_exec_context pref_context);
-+
-+void scst_rx_data(struct scst_cmd *cmd, int status,
-+ enum scst_exec_context pref_context);
-+
-+void scst_tgt_cmd_done(struct scst_cmd *cmd,
-+ enum scst_exec_context pref_context);
-+
-+int scst_rx_mgmt_fn(struct scst_session *sess,
-+ const struct scst_rx_mgmt_params *params);
-+
-+/*
-+ * Creates new management command using tag and sends it for execution.
-+ * Can be used for SCST_ABORT_TASK only.
-+ * Must not be called in parallel with scst_unregister_session() for the
-+ * same sess. Returns 0 for success, error code otherwise.
-+ *
-+ * Obsolete in favor of scst_rx_mgmt_fn()
-+ */
-+static inline int scst_rx_mgmt_fn_tag(struct scst_session *sess, int fn,
-+ uint64_t tag, int atomic, void *tgt_priv)
-+{
-+ struct scst_rx_mgmt_params params;
-+
-+ BUG_ON(fn != SCST_ABORT_TASK);
-+
-+ memset(&params, 0, sizeof(params));
-+ params.fn = fn;
-+ params.tag = tag;
-+ params.tag_set = 1;
-+ params.atomic = atomic;
-+ params.tgt_priv = tgt_priv;
-+ return scst_rx_mgmt_fn(sess, &params);
-+}
-+
-+/*
-+ * Creates new management command using LUN and sends it for execution.
-+ * Currently can be used for any fn, except SCST_ABORT_TASK.
-+ * Must not be called in parallel with scst_unregister_session() for the
-+ * same sess. Returns 0 for success, error code otherwise.
-+ *
-+ * Obsolete in favor of scst_rx_mgmt_fn()
-+ */
-+static inline int scst_rx_mgmt_fn_lun(struct scst_session *sess, int fn,
-+ const uint8_t *lun, int lun_len, int atomic, void *tgt_priv)
-+{
-+ struct scst_rx_mgmt_params params;
-+
-+ BUG_ON(fn == SCST_ABORT_TASK);
-+
-+ memset(&params, 0, sizeof(params));
-+ params.fn = fn;
-+ params.lun = lun;
-+ params.lun_len = lun_len;
-+ params.lun_set = 1;
-+ params.atomic = atomic;
-+ params.tgt_priv = tgt_priv;
-+ return scst_rx_mgmt_fn(sess, &params);
-+}
-+
-+int scst_get_cdb_info(struct scst_cmd *cmd);
-+
-+int scst_set_cmd_error_status(struct scst_cmd *cmd, int status);
-+int scst_set_cmd_error(struct scst_cmd *cmd, int key, int asc, int ascq);
-+void scst_set_busy(struct scst_cmd *cmd);
-+
-+void scst_check_convert_sense(struct scst_cmd *cmd);
-+
-+void scst_set_initial_UA(struct scst_session *sess, int key, int asc, int ascq);
-+
-+void scst_capacity_data_changed(struct scst_device *dev);
-+
-+struct scst_cmd *scst_find_cmd_by_tag(struct scst_session *sess, uint64_t tag);
-+struct scst_cmd *scst_find_cmd(struct scst_session *sess, void *data,
-+ int (*cmp_fn) (struct scst_cmd *cmd,
-+ void *data));
-+
-+enum dma_data_direction scst_to_dma_dir(int scst_dir);
-+enum dma_data_direction scst_to_tgt_dma_dir(int scst_dir);
-+
-+/*
-+ * Returns true, if cmd's CDB is fully locally handled by SCST and false
-+ * otherwise. Dev handlers parse() and dev_done() not called for such commands.
-+ */
-+static inline bool scst_is_cmd_fully_local(struct scst_cmd *cmd)
-+{
-+ return (cmd->op_flags & SCST_FULLY_LOCAL_CMD) != 0;
-+}
-+
-+/*
-+ * Returns true, if cmd's CDB is locally handled by SCST and
-+ * false otherwise.
-+ */
-+static inline bool scst_is_cmd_local(struct scst_cmd *cmd)
-+{
-+ return (cmd->op_flags & SCST_LOCAL_CMD) != 0;
-+}
-+
-+/* Returns true, if cmd can deliver UA */
-+static inline bool scst_is_ua_command(struct scst_cmd *cmd)
-+{
-+ return (cmd->op_flags & SCST_SKIP_UA) == 0;
-+}
-+
-+int scst_register_virtual_device(struct scst_dev_type *dev_handler,
-+ const char *dev_name);
-+void scst_unregister_virtual_device(int id);
-+
-+/*
-+ * Get/Set functions for tgt's sg_tablesize
-+ */
-+static inline int scst_tgt_get_sg_tablesize(struct scst_tgt *tgt)
-+{
-+ return tgt->sg_tablesize;
-+}
-+
-+static inline void scst_tgt_set_sg_tablesize(struct scst_tgt *tgt, int val)
-+{
-+ tgt->sg_tablesize = val;
-+}
-+
-+/*
-+ * Get/Set functions for tgt's target private data
-+ */
-+static inline void *scst_tgt_get_tgt_priv(struct scst_tgt *tgt)
-+{
-+ return tgt->tgt_priv;
-+}
-+
-+static inline void scst_tgt_set_tgt_priv(struct scst_tgt *tgt, void *val)
-+{
-+ tgt->tgt_priv = val;
-+}
-+
-+void scst_update_hw_pending_start(struct scst_cmd *cmd);
-+
-+/*
-+ * Get/Set functions for session's target private data
-+ */
-+static inline void *scst_sess_get_tgt_priv(struct scst_session *sess)
-+{
-+ return sess->tgt_priv;
-+}
-+
-+static inline void scst_sess_set_tgt_priv(struct scst_session *sess,
-+ void *val)
-+{
-+ sess->tgt_priv = val;
-+}
-+
-+uint16_t scst_lookup_tg_id(struct scst_device *dev, struct scst_tgt *tgt);
-+bool scst_impl_alua_configured(struct scst_device *dev);
-+int scst_tg_get_group_info(void **buf, uint32_t *response_length,
-+ struct scst_device *dev, uint8_t data_format);
-+
-+/**
-+ * Returns TRUE if cmd is being executed in atomic context.
-+ *
-+ * This function must be used outside of spinlocks and preempt/BH/IRQ
-+ * disabled sections, because of the EXTRACHECK in it.
-+ */
-+static inline bool scst_cmd_atomic(struct scst_cmd *cmd)
-+{
-+ int res = cmd->atomic;
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ /*
-+ * Checkpatch will complain on the use of in_atomic() below. You
-+ * can safely ignore this warning since in_atomic() is used here
-+ * only for debugging purposes.
-+ */
-+ if (unlikely((in_atomic() || in_interrupt() || irqs_disabled()) &&
-+ !res)) {
-+ printk(KERN_ERR "ERROR: atomic context and non-atomic cmd!\n");
-+ dump_stack();
-+ cmd->atomic = 1;
-+ res = 1;
-+ }
-+#endif
-+ return res;
-+}
-+
-+/*
-+ * Returns TRUE if cmd has been preliminary completed, i.e. completed or
-+ * aborted.
-+ */
-+static inline bool scst_cmd_prelim_completed(struct scst_cmd *cmd)
-+{
-+ return cmd->completed || test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags);
-+}
-+
-+static inline enum scst_exec_context __scst_estimate_context(bool atomic)
-+{
-+ if (in_irq())
-+ return SCST_CONTEXT_TASKLET;
-+/*
-+ * We come here from many non reliable places, like the block layer, and don't
-+ * have any reliable way to detect if we called under atomic context or not
-+ * (in_atomic() isn't reliable), so let's be safe and disable this section
-+ * for now to unconditionally return thread context.
-+ */
-+#if 0
-+ else if (irqs_disabled())
-+ return SCST_CONTEXT_THREAD;
-+ else if (in_atomic())
-+ return SCST_CONTEXT_DIRECT_ATOMIC;
-+ else
-+ return atomic ? SCST_CONTEXT_DIRECT :
-+ SCST_CONTEXT_DIRECT_ATOMIC;
-+#else
-+ return SCST_CONTEXT_THREAD;
-+#endif
-+}
-+
-+static inline enum scst_exec_context scst_estimate_context(void)
-+{
-+ return __scst_estimate_context(false);
-+}
-+
-+static inline enum scst_exec_context scst_estimate_context_atomic(void)
-+{
-+ return __scst_estimate_context(true);
-+}
-+
-+/* Returns cmd's CDB */
-+static inline const uint8_t *scst_cmd_get_cdb(struct scst_cmd *cmd)
-+{
-+ return cmd->cdb;
-+}
-+
-+/* Returns cmd's CDB length */
-+static inline unsigned int scst_cmd_get_cdb_len(struct scst_cmd *cmd)
-+{
-+ return cmd->cdb_len;
-+}
-+
-+void scst_cmd_set_ext_cdb(struct scst_cmd *cmd,
-+ uint8_t *ext_cdb, unsigned int ext_cdb_len, gfp_t gfp_mask);
-+
-+/* Returns cmd's session */
-+static inline struct scst_session *scst_cmd_get_session(struct scst_cmd *cmd)
-+{
-+ return cmd->sess;
-+}
-+
-+/* Returns cmd's response data length */
-+static inline int scst_cmd_get_resp_data_len(struct scst_cmd *cmd)
-+{
-+ return cmd->resp_data_len;
-+}
-+
-+/* Returns cmd's adjusted response data length */
-+static inline int scst_cmd_get_adjusted_resp_data_len(struct scst_cmd *cmd)
-+{
-+ return cmd->adjusted_resp_data_len;
-+}
-+
-+/* Returns if status should be sent for cmd */
-+static inline int scst_cmd_get_is_send_status(struct scst_cmd *cmd)
-+{
-+ return cmd->is_send_status;
-+}
-+
-+/*
-+ * Returns pointer to cmd's SG data buffer.
-+ *
-+ * Usage of this function is not recommended, use scst_get_buf_*()
-+ * family of functions instead.
-+ */
-+static inline struct scatterlist *scst_cmd_get_sg(struct scst_cmd *cmd)
-+{
-+ return cmd->sg;
-+}
-+
-+/*
-+ * Returns cmd's sg_cnt.
-+ *
-+ * Usage of this function is not recommended, use scst_get_buf_*()
-+ * family of functions instead.
-+ */
-+static inline int scst_cmd_get_sg_cnt(struct scst_cmd *cmd)
-+{
-+ return cmd->sg_cnt;
-+}
-+
-+/*
-+ * Returns cmd's data buffer length.
-+ *
-+ * In case if you need to iterate over data in the buffer, usage of
-+ * this function is not recommended, use scst_get_buf_*()
-+ * family of functions instead.
-+ */
-+static inline unsigned int scst_cmd_get_bufflen(struct scst_cmd *cmd)
-+{
-+ return cmd->bufflen;
-+}
-+
-+/*
-+ * Returns pointer to cmd's bidirectional in (WRITE) SG data buffer.
-+ *
-+ * Usage of this function is not recommended, use scst_get_out_buf_*()
-+ * family of functions instead.
-+ */
-+static inline struct scatterlist *scst_cmd_get_out_sg(struct scst_cmd *cmd)
-+{
-+ return cmd->out_sg;
-+}
-+
-+/*
-+ * Returns cmd's bidirectional in (WRITE) sg_cnt.
-+ *
-+ * Usage of this function is not recommended, use scst_get_out_buf_*()
-+ * family of functions instead.
-+ */
-+static inline int scst_cmd_get_out_sg_cnt(struct scst_cmd *cmd)
-+{
-+ return cmd->out_sg_cnt;
-+}
-+
-+void scst_restore_sg_buff(struct scst_cmd *cmd);
-+
-+/* Restores modified sg buffer in the original state, if necessary */
-+static inline void scst_check_restore_sg_buff(struct scst_cmd *cmd)
-+{
-+ if (unlikely(cmd->sg_buff_modified))
-+ scst_restore_sg_buff(cmd);
-+}
-+
-+/*
-+ * Returns cmd's bidirectional in (WRITE) data buffer length.
-+ *
-+ * In case if you need to iterate over data in the buffer, usage of
-+ * this function is not recommended, use scst_get_out_buf_*()
-+ * family of functions instead.
-+ */
-+static inline unsigned int scst_cmd_get_out_bufflen(struct scst_cmd *cmd)
-+{
-+ return cmd->out_bufflen;
-+}
-+
-+/* Returns pointer to cmd's target's SG data buffer */
-+static inline struct scatterlist *scst_cmd_get_tgt_sg(struct scst_cmd *cmd)
-+{
-+ return cmd->tgt_sg;
-+}
-+
-+/* Returns cmd's target's sg_cnt */
-+static inline int scst_cmd_get_tgt_sg_cnt(struct scst_cmd *cmd)
-+{
-+ return cmd->tgt_sg_cnt;
-+}
-+
-+/* Sets cmd's target's SG data buffer */
-+static inline void scst_cmd_set_tgt_sg(struct scst_cmd *cmd,
-+ struct scatterlist *sg, int sg_cnt)
-+{
-+ cmd->tgt_sg = sg;
-+ cmd->tgt_sg_cnt = sg_cnt;
-+ cmd->tgt_data_buf_alloced = 1;
-+}
-+
-+/* Returns pointer to cmd's target's OUT SG data buffer */
-+static inline struct scatterlist *scst_cmd_get_out_tgt_sg(struct scst_cmd *cmd)
-+{
-+ return cmd->tgt_out_sg;
-+}
-+
-+/* Returns cmd's target's OUT sg_cnt */
-+static inline int scst_cmd_get_tgt_out_sg_cnt(struct scst_cmd *cmd)
-+{
-+ return cmd->tgt_out_sg_cnt;
-+}
-+
-+/* Sets cmd's target's OUT SG data buffer */
-+static inline void scst_cmd_set_tgt_out_sg(struct scst_cmd *cmd,
-+ struct scatterlist *sg, int sg_cnt)
-+{
-+ WARN_ON(!cmd->tgt_data_buf_alloced);
-+
-+ cmd->tgt_out_sg = sg;
-+ cmd->tgt_out_sg_cnt = sg_cnt;
-+}
-+
-+/* Returns cmd's data direction */
-+static inline scst_data_direction scst_cmd_get_data_direction(
-+ struct scst_cmd *cmd)
-+{
-+ return cmd->data_direction;
-+}
-+
-+/* Returns cmd's write len as well as write SG and sg_cnt */
-+static inline int scst_cmd_get_write_fields(struct scst_cmd *cmd,
-+ struct scatterlist **sg, int *sg_cnt)
-+{
-+ *sg = *cmd->write_sg;
-+ *sg_cnt = *cmd->write_sg_cnt;
-+ return cmd->write_len;
-+}
-+
-+void scst_cmd_set_write_not_received_data_len(struct scst_cmd *cmd,
-+ int not_received);
-+
-+bool __scst_get_resid(struct scst_cmd *cmd, int *resid, int *bidi_out_resid);
-+
-+/*
-+ * Returns true if cmd has residual(s) and returns them in the corresponding
-+ * parameters(s).
-+ */
-+static inline bool scst_get_resid(struct scst_cmd *cmd,
-+ int *resid, int *bidi_out_resid)
-+{
-+ if (likely(!cmd->resid_possible))
-+ return false;
-+ return __scst_get_resid(cmd, resid, bidi_out_resid);
-+}
-+
-+/* Returns cmd's status byte from host device */
-+static inline uint8_t scst_cmd_get_status(struct scst_cmd *cmd)
-+{
-+ return cmd->status;
-+}
-+
-+/* Returns cmd's status from host adapter itself */
-+static inline uint8_t scst_cmd_get_msg_status(struct scst_cmd *cmd)
-+{
-+ return cmd->msg_status;
-+}
-+
-+/* Returns cmd's status set by low-level driver to indicate its status */
-+static inline uint8_t scst_cmd_get_host_status(struct scst_cmd *cmd)
-+{
-+ return cmd->host_status;
-+}
-+
-+/* Returns cmd's status set by SCSI mid-level */
-+static inline uint8_t scst_cmd_get_driver_status(struct scst_cmd *cmd)
-+{
-+ return cmd->driver_status;
-+}
-+
-+/* Returns pointer to cmd's sense buffer */
-+static inline uint8_t *scst_cmd_get_sense_buffer(struct scst_cmd *cmd)
-+{
-+ return cmd->sense;
-+}
-+
-+/* Returns cmd's valid sense length */
-+static inline int scst_cmd_get_sense_buffer_len(struct scst_cmd *cmd)
-+{
-+ return cmd->sense_valid_len;
-+}
-+
-+/*
-+ * Get/Set functions for cmd's queue_type
-+ */
-+static inline enum scst_cmd_queue_type scst_cmd_get_queue_type(
-+ struct scst_cmd *cmd)
-+{
-+ return cmd->queue_type;
-+}
-+
-+static inline void scst_cmd_set_queue_type(struct scst_cmd *cmd,
-+ enum scst_cmd_queue_type queue_type)
-+{
-+ cmd->queue_type = queue_type;
-+}
-+
-+/*
-+ * Get/Set functions for cmd's target SN
-+ */
-+static inline uint64_t scst_cmd_get_tag(struct scst_cmd *cmd)
-+{
-+ return cmd->tag;
-+}
-+
-+static inline void scst_cmd_set_tag(struct scst_cmd *cmd, uint64_t tag)
-+{
-+ cmd->tag = tag;
-+}
-+
-+/*
-+ * Get/Set functions for cmd's target private data.
-+ * Variant with *_lock must be used if target driver uses
-+ * scst_find_cmd() to avoid race with it, except inside scst_find_cmd()'s
-+ * callback, where lock is already taken.
-+ */
-+static inline void *scst_cmd_get_tgt_priv(struct scst_cmd *cmd)
-+{
-+ return cmd->tgt_priv;
-+}
-+
-+static inline void scst_cmd_set_tgt_priv(struct scst_cmd *cmd, void *val)
-+{
-+ cmd->tgt_priv = val;
-+}
-+
-+/*
-+ * Get/Set functions for tgt_need_alloc_data_buf flag
-+ */
-+static inline int scst_cmd_get_tgt_need_alloc_data_buf(struct scst_cmd *cmd)
-+{
-+ return cmd->tgt_need_alloc_data_buf;
-+}
-+
-+static inline void scst_cmd_set_tgt_need_alloc_data_buf(struct scst_cmd *cmd)
-+{
-+ cmd->tgt_need_alloc_data_buf = 1;
-+}
-+
-+/*
-+ * Get/Set functions for tgt_data_buf_alloced flag
-+ */
-+static inline int scst_cmd_get_tgt_data_buff_alloced(struct scst_cmd *cmd)
-+{
-+ return cmd->tgt_data_buf_alloced;
-+}
-+
-+static inline void scst_cmd_set_tgt_data_buff_alloced(struct scst_cmd *cmd)
-+{
-+ cmd->tgt_data_buf_alloced = 1;
-+}
-+
-+/*
-+ * Get/Set functions for dh_data_buf_alloced flag
-+ */
-+static inline int scst_cmd_get_dh_data_buff_alloced(struct scst_cmd *cmd)
-+{
-+ return cmd->dh_data_buf_alloced;
-+}
-+
-+static inline void scst_cmd_set_dh_data_buff_alloced(struct scst_cmd *cmd)
-+{
-+ cmd->dh_data_buf_alloced = 1;
-+}
-+
-+/*
-+ * Get/Set functions for no_sgv flag
-+ */
-+static inline int scst_cmd_get_no_sgv(struct scst_cmd *cmd)
-+{
-+ return cmd->no_sgv;
-+}
-+
-+static inline void scst_cmd_set_no_sgv(struct scst_cmd *cmd)
-+{
-+ cmd->no_sgv = 1;
-+}
-+
-+/*
-+ * Get/Set functions for tgt_sn
-+ */
-+static inline int scst_cmd_get_tgt_sn(struct scst_cmd *cmd)
-+{
-+ BUG_ON(!cmd->tgt_sn_set);
-+ return cmd->tgt_sn;
-+}
-+
-+static inline void scst_cmd_set_tgt_sn(struct scst_cmd *cmd, uint32_t tgt_sn)
-+{
-+ cmd->tgt_sn_set = 1;
-+ cmd->tgt_sn = tgt_sn;
-+}
-+
-+/*
-+ * Get/Set functions for noio_mem_alloc
-+ */
-+static inline bool scst_cmd_get_noio_mem_alloc(struct scst_cmd *cmd)
-+{
-+ return cmd->noio_mem_alloc;
-+}
-+
-+static inline void scst_cmd_set_noio_mem_alloc(struct scst_cmd *cmd)
-+{
-+ cmd->noio_mem_alloc = 1;
-+}
-+
-+/*
-+ * Returns 1 if the cmd was aborted, so its status is invalid and no
-+ * reply shall be sent to the remote initiator. A target driver should
-+ * only clear internal resources, associated with cmd.
-+ */
-+static inline int scst_cmd_aborted(struct scst_cmd *cmd)
-+{
-+ return test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags) &&
-+ !test_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags);
-+}
-+
-+/* Returns sense data format for cmd's dev */
-+static inline bool scst_get_cmd_dev_d_sense(struct scst_cmd *cmd)
-+{
-+ return (cmd->dev != NULL) ? cmd->dev->d_sense : 0;
-+}
-+
-+/*
-+ * Get/Set functions for expected data direction, transfer length
-+ * and its validity flag
-+ */
-+static inline int scst_cmd_is_expected_set(struct scst_cmd *cmd)
-+{
-+ return cmd->expected_values_set;
-+}
-+
-+static inline scst_data_direction scst_cmd_get_expected_data_direction(
-+ struct scst_cmd *cmd)
-+{
-+ return cmd->expected_data_direction;
-+}
-+
-+static inline int scst_cmd_get_expected_transfer_len(
-+ struct scst_cmd *cmd)
-+{
-+ return cmd->expected_transfer_len;
-+}
-+
-+static inline int scst_cmd_get_expected_out_transfer_len(
-+ struct scst_cmd *cmd)
-+{
-+ return cmd->expected_out_transfer_len;
-+}
-+
-+static inline void scst_cmd_set_expected(struct scst_cmd *cmd,
-+ scst_data_direction expected_data_direction,
-+ int expected_transfer_len)
-+{
-+ cmd->expected_data_direction = expected_data_direction;
-+ cmd->expected_transfer_len = expected_transfer_len;
-+ cmd->expected_values_set = 1;
-+}
-+
-+static inline void scst_cmd_set_expected_out_transfer_len(struct scst_cmd *cmd,
-+ int expected_out_transfer_len)
-+{
-+ WARN_ON(!cmd->expected_values_set);
-+ cmd->expected_out_transfer_len = expected_out_transfer_len;
-+}
-+
-+/*
-+ * Get/clear functions for cmd's may_need_dma_sync
-+ */
-+static inline int scst_get_may_need_dma_sync(struct scst_cmd *cmd)
-+{
-+ return cmd->may_need_dma_sync;
-+}
-+
-+static inline void scst_clear_may_need_dma_sync(struct scst_cmd *cmd)
-+{
-+ cmd->may_need_dma_sync = 0;
-+}
-+
-+/*
-+ * Get/set functions for cmd's delivery_status. It is one of
-+ * SCST_CMD_DELIVERY_* constants. It specifies the status of the
-+ * command's delivery to initiator.
-+ */
-+static inline int scst_get_delivery_status(struct scst_cmd *cmd)
-+{
-+ return cmd->delivery_status;
-+}
-+
-+static inline void scst_set_delivery_status(struct scst_cmd *cmd,
-+ int delivery_status)
-+{
-+ cmd->delivery_status = delivery_status;
-+}
-+
-+static inline unsigned int scst_get_active_cmd_count(struct scst_cmd *cmd)
-+{
-+ if (likely(cmd->tgt_dev != NULL))
-+ return atomic_read(&cmd->tgt_dev->tgt_dev_cmd_count);
-+ else
-+ return (unsigned int)-1;
-+}
-+
-+/*
-+ * Get/Set function for mgmt cmd's target private data
-+ */
-+static inline void *scst_mgmt_cmd_get_tgt_priv(struct scst_mgmt_cmd *mcmd)
-+{
-+ return mcmd->tgt_priv;
-+}
-+
-+static inline void scst_mgmt_cmd_set_tgt_priv(struct scst_mgmt_cmd *mcmd,
-+ void *val)
-+{
-+ mcmd->tgt_priv = val;
-+}
-+
-+/* Returns mgmt cmd's completion status (SCST_MGMT_STATUS_* constants) */
-+static inline int scst_mgmt_cmd_get_status(struct scst_mgmt_cmd *mcmd)
-+{
-+ return mcmd->status;
-+}
-+
-+/* Returns mgmt cmd's TM fn */
-+static inline int scst_mgmt_cmd_get_fn(struct scst_mgmt_cmd *mcmd)
-+{
-+ return mcmd->fn;
-+}
-+
-+/*
-+ * Called by dev handler's task_mgmt_fn() to notify SCST core that mcmd
-+ * is going to complete asynchronously.
-+ */
-+void scst_prepare_async_mcmd(struct scst_mgmt_cmd *mcmd);
-+
-+/*
-+ * Called by dev handler to notify SCST core that async. mcmd is completed
-+ * with status "status".
-+ */
-+void scst_async_mcmd_completed(struct scst_mgmt_cmd *mcmd, int status);
-+
-+/* Returns AEN's fn */
-+static inline int scst_aen_get_event_fn(struct scst_aen *aen)
-+{
-+ return aen->event_fn;
-+}
-+
-+/* Returns AEN's session */
-+static inline struct scst_session *scst_aen_get_sess(struct scst_aen *aen)
-+{
-+ return aen->sess;
-+}
-+
-+/* Returns AEN's LUN */
-+static inline __be64 scst_aen_get_lun(struct scst_aen *aen)
-+{
-+ return aen->lun;
-+}
-+
-+/* Returns SCSI AEN's sense */
-+static inline const uint8_t *scst_aen_get_sense(struct scst_aen *aen)
-+{
-+ return aen->aen_sense;
-+}
-+
-+/* Returns SCSI AEN's sense length */
-+static inline int scst_aen_get_sense_len(struct scst_aen *aen)
-+{
-+ return aen->aen_sense_len;
-+}
-+
-+/*
-+ * Get/set functions for AEN's delivery_status. It is one of
-+ * SCST_AEN_RES_* constants. It specifies the status of the
-+ * command's delivery to initiator.
-+ */
-+static inline int scst_get_aen_delivery_status(struct scst_aen *aen)
-+{
-+ return aen->delivery_status;
-+}
-+
-+static inline void scst_set_aen_delivery_status(struct scst_aen *aen,
-+ int status)
-+{
-+ aen->delivery_status = status;
-+}
-+
-+void scst_aen_done(struct scst_aen *aen);
-+
-+static inline void sg_clear(struct scatterlist *sg)
-+{
-+ memset(sg, 0, sizeof(*sg));
-+#ifdef CONFIG_DEBUG_SG
-+ sg->sg_magic = SG_MAGIC;
-+#endif
-+}
-+
-+enum scst_sg_copy_dir {
-+ SCST_SG_COPY_FROM_TARGET,
-+ SCST_SG_COPY_TO_TARGET
-+};
-+
-+void scst_copy_sg(struct scst_cmd *cmd, enum scst_sg_copy_dir copy_dir);
-+
-+/*
-+ * Functions for access to the commands data (SG) buffer. Should be used
-+ * instead of direct access. Returns the buffer length for success, 0 for EOD,
-+ * negative error code otherwise.
-+ *
-+ * Never EVER use this function to process only "the first page" of the buffer.
-+ * The first SG entry can be as low as few bytes long. Use scst_get_buf_full()
-+ * instead for such cases.
-+ *
-+ * "Buf" argument returns the mapped buffer
-+ *
-+ * The "put" function unmaps the buffer.
-+ */
-+static inline int __scst_get_buf(struct scst_cmd *cmd, int sg_cnt,
-+ uint8_t **buf)
-+{
-+ int res = 0;
-+ struct scatterlist *sg = cmd->get_sg_buf_cur_sg_entry;
-+
-+ if (cmd->get_sg_buf_entry_num >= sg_cnt) {
-+ *buf = NULL;
-+ goto out;
-+ }
-+
-+ if (unlikely(sg_is_chain(sg)))
-+ sg = sg_chain_ptr(sg);
-+
-+ *buf = page_address(sg_page(sg));
-+ *buf += sg->offset;
-+
-+ res = sg->length;
-+
-+ cmd->get_sg_buf_entry_num++;
-+ cmd->get_sg_buf_cur_sg_entry = ++sg;
-+
-+out:
-+ return res;
-+}
-+
-+static inline int scst_get_buf_first(struct scst_cmd *cmd, uint8_t **buf)
-+{
-+ if (unlikely(cmd->sg == NULL)) {
-+ *buf = NULL;
-+ return 0;
-+ }
-+ cmd->get_sg_buf_entry_num = 0;
-+ cmd->get_sg_buf_cur_sg_entry = cmd->sg;
-+ cmd->may_need_dma_sync = 1;
-+ return __scst_get_buf(cmd, cmd->sg_cnt, buf);
-+}
-+
-+static inline int scst_get_buf_next(struct scst_cmd *cmd, uint8_t **buf)
-+{
-+ return __scst_get_buf(cmd, cmd->sg_cnt, buf);
-+}
-+
-+static inline void scst_put_buf(struct scst_cmd *cmd, void *buf)
-+{
-+ /* Nothing to do */
-+}
-+
-+static inline int scst_get_out_buf_first(struct scst_cmd *cmd, uint8_t **buf)
-+{
-+ if (unlikely(cmd->out_sg == NULL)) {
-+ *buf = NULL;
-+ return 0;
-+ }
-+ cmd->get_sg_buf_entry_num = 0;
-+ cmd->get_sg_buf_cur_sg_entry = cmd->out_sg;
-+ cmd->may_need_dma_sync = 1;
-+ return __scst_get_buf(cmd, cmd->out_sg_cnt, buf);
-+}
-+
-+static inline int scst_get_out_buf_next(struct scst_cmd *cmd, uint8_t **buf)
-+{
-+ return __scst_get_buf(cmd, cmd->out_sg_cnt, buf);
-+}
-+
-+static inline void scst_put_out_buf(struct scst_cmd *cmd, void *buf)
-+{
-+ /* Nothing to do */
-+}
-+
-+static inline int scst_get_sg_buf_first(struct scst_cmd *cmd, uint8_t **buf,
-+ struct scatterlist *sg, int sg_cnt)
-+{
-+ if (unlikely(sg == NULL)) {
-+ *buf = NULL;
-+ return 0;
-+ }
-+ cmd->get_sg_buf_entry_num = 0;
-+ cmd->get_sg_buf_cur_sg_entry = cmd->sg;
-+ cmd->may_need_dma_sync = 1;
-+ return __scst_get_buf(cmd, sg_cnt, buf);
-+}
-+
-+static inline int scst_get_sg_buf_next(struct scst_cmd *cmd, uint8_t **buf,
-+ struct scatterlist *sg, int sg_cnt)
-+{
-+ return __scst_get_buf(cmd, sg_cnt, buf);
-+}
-+
-+static inline void scst_put_sg_buf(struct scst_cmd *cmd, void *buf,
-+ struct scatterlist *sg, int sg_cnt)
-+{
-+ /* Nothing to do */
-+}
-+
-+/*
-+ * Functions for access to the commands data (SG) page. Should be used
-+ * instead of direct access. Returns the buffer length for success, 0 for EOD,
-+ * negative error code otherwise.
-+ *
-+ * "Page" argument returns the starting page, "offset" - offset in it.
-+ *
-+ * The "put" function "puts" the buffer. It should be always be used, because
-+ * in future may need to do some additional operations.
-+ */
-+static inline int __scst_get_sg_page(struct scst_cmd *cmd, int sg_cnt,
-+ struct page **page, int *offset)
-+{
-+ int res = 0;
-+ struct scatterlist *sg = cmd->get_sg_buf_cur_sg_entry;
-+
-+ if (cmd->get_sg_buf_entry_num >= sg_cnt) {
-+ *page = NULL;
-+ *offset = 0;
-+ goto out;
-+ }
-+
-+ if (unlikely(sg_is_chain(sg)))
-+ sg = sg_chain_ptr(sg);
-+
-+ *page = sg_page(sg);
-+ *offset = sg->offset;
-+ res = sg->length;
-+
-+ cmd->get_sg_buf_entry_num++;
-+ cmd->get_sg_buf_cur_sg_entry = ++sg;
-+
-+out:
-+ return res;
-+}
-+
-+static inline int scst_get_sg_page_first(struct scst_cmd *cmd,
-+ struct page **page, int *offset)
-+{
-+ if (unlikely(cmd->sg == NULL)) {
-+ *page = NULL;
-+ *offset = 0;
-+ return 0;
-+ }
-+ cmd->get_sg_buf_entry_num = 0;
-+ cmd->get_sg_buf_cur_sg_entry = cmd->sg;
-+ return __scst_get_sg_page(cmd, cmd->sg_cnt, page, offset);
-+}
-+
-+static inline int scst_get_sg_page_next(struct scst_cmd *cmd,
-+ struct page **page, int *offset)
-+{
-+ return __scst_get_sg_page(cmd, cmd->sg_cnt, page, offset);
-+}
-+
-+static inline void scst_put_sg_page(struct scst_cmd *cmd,
-+ struct page *page, int offset)
-+{
-+ /* Nothing to do */
-+}
-+
-+static inline int scst_get_out_sg_page_first(struct scst_cmd *cmd,
-+ struct page **page, int *offset)
-+{
-+ if (unlikely(cmd->out_sg == NULL)) {
-+ *page = NULL;
-+ *offset = 0;
-+ return 0;
-+ }
-+ cmd->get_sg_buf_entry_num = 0;
-+ cmd->get_sg_buf_cur_sg_entry = cmd->out_sg;
-+ return __scst_get_sg_page(cmd, cmd->out_sg_cnt, page, offset);
-+}
-+
-+static inline int scst_get_out_sg_page_next(struct scst_cmd *cmd,
-+ struct page **page, int *offset)
-+{
-+ return __scst_get_sg_page(cmd, cmd->out_sg_cnt, page, offset);
-+}
-+
-+static inline void scst_put_out_sg_page(struct scst_cmd *cmd,
-+ struct page *page, int offset)
-+{
-+ /* Nothing to do */
-+}
-+
-+/*
-+ * Returns approximate higher rounded buffers count that
-+ * scst_get_buf_[first|next]() return.
-+ */
-+static inline int scst_get_buf_count(struct scst_cmd *cmd)
-+{
-+ return (cmd->sg_cnt == 0) ? 1 : cmd->sg_cnt;
-+}
-+
-+/*
-+ * Returns approximate higher rounded buffers count that
-+ * scst_get_out_buf_[first|next]() return.
-+ */
-+static inline int scst_get_out_buf_count(struct scst_cmd *cmd)
-+{
-+ return (cmd->out_sg_cnt == 0) ? 1 : cmd->out_sg_cnt;
-+}
-+
-+int scst_get_buf_full(struct scst_cmd *cmd, uint8_t **buf);
-+void scst_put_buf_full(struct scst_cmd *cmd, uint8_t *buf);
-+
-+#ifdef CONFIG_DEBUG_LOCK_ALLOC
-+extern struct lockdep_map scst_suspend_dep_map;
-+#define scst_assert_activity_suspended() \
-+ WARN_ON(debug_locks && !lock_is_held(&scst_suspend_dep_map));
-+#else
-+#define scst_assert_activity_suspended() do { } while (0)
-+#endif
-+int scst_suspend_activity(bool interruptible);
-+void scst_resume_activity(void);
-+
-+void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic);
-+
-+void scst_post_parse(struct scst_cmd *cmd);
-+void scst_post_alloc_data_buf(struct scst_cmd *cmd);
-+
-+int scst_check_local_events(struct scst_cmd *cmd);
-+
-+static inline int scst_pre_check_local_events(struct scst_cmd *cmd)
-+{
-+ int res = scst_check_local_events(cmd);
-+ cmd->check_local_events_once_done = 1;
-+ return res;
-+}
-+
-+int scst_set_cmd_abnormal_done_state(struct scst_cmd *cmd);
-+
-+struct scst_trace_log {
-+ unsigned int val;
-+ const char *token;
-+};
-+
-+extern struct mutex scst_mutex;
-+
-+const struct sysfs_ops *scst_sysfs_get_sysfs_ops(void);
-+
-+/*
-+ * 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;
-+}
-+
-+/*
-+ * Returns session's root sysfs kobject.
-+ * The driver can create own files/directories/links here.
-+ */
-+static inline struct kobject *scst_sysfs_get_sess_kobj(
-+ struct scst_session *sess)
-+{
-+ return &sess->sess_kobj;
-+}
-+
-+/* Returns target name */
-+static inline const char *scst_get_tgt_name(const struct scst_tgt *tgt)
-+{
-+ return tgt->tgt_name;
-+}
-+
-+int scst_alloc_sense(struct scst_cmd *cmd, int atomic);
-+int scst_alloc_set_sense(struct scst_cmd *cmd, int atomic,
-+ const uint8_t *sense, unsigned int len);
-+
-+int scst_set_sense(uint8_t *buffer, int len, bool d_sense,
-+ int key, int asc, int ascq);
-+
-+bool scst_is_ua_sense(const uint8_t *sense, int len);
-+
-+bool scst_analyze_sense(const uint8_t *sense, int len,
-+ unsigned int valid_mask, int key, int asc, int ascq);
-+
-+unsigned long scst_random(void);
-+
-+void scst_set_resp_data_len(struct scst_cmd *cmd, int resp_data_len);
-+
-+void scst_cmd_get(struct scst_cmd *cmd);
-+void scst_cmd_put(struct scst_cmd *cmd);
-+
-+struct scatterlist *scst_alloc(int size, gfp_t gfp_mask, int *count);
-+void scst_free(struct scatterlist *sg, int count);
-+
-+void scst_add_thr_data(struct scst_tgt_dev *tgt_dev,
-+ struct scst_thr_data_hdr *data,
-+ void (*free_fn) (struct scst_thr_data_hdr *data));
-+void scst_del_all_thr_data(struct scst_tgt_dev *tgt_dev);
-+void scst_dev_del_all_thr_data(struct scst_device *dev);
-+struct scst_thr_data_hdr *__scst_find_thr_data(struct scst_tgt_dev *tgt_dev,
-+ struct task_struct *tsk);
-+
-+/* Finds local to the current thread data. Returns NULL, if they not found. */
-+static inline struct scst_thr_data_hdr *scst_find_thr_data(
-+ struct scst_tgt_dev *tgt_dev)
-+{
-+ return __scst_find_thr_data(tgt_dev, current);
-+}
-+
-+/* Increase ref counter for the thread data */
-+static inline void scst_thr_data_get(struct scst_thr_data_hdr *data)
-+{
-+ atomic_inc(&data->ref);
-+}
-+
-+/* Decrease ref counter for the thread data */
-+static inline void scst_thr_data_put(struct scst_thr_data_hdr *data)
-+{
-+ if (atomic_dec_and_test(&data->ref))
-+ data->free_fn(data);
-+}
-+
-+int scst_calc_block_shift(int sector_size);
-+int scst_sbc_generic_parse(struct scst_cmd *cmd,
-+ int (*get_block_shift)(struct scst_cmd *cmd));
-+int scst_cdrom_generic_parse(struct scst_cmd *cmd,
-+ int (*get_block_shift)(struct scst_cmd *cmd));
-+int scst_modisk_generic_parse(struct scst_cmd *cmd,
-+ int (*get_block_shift)(struct scst_cmd *cmd));
-+int scst_tape_generic_parse(struct scst_cmd *cmd,
-+ int (*get_block_size)(struct scst_cmd *cmd));
-+int scst_changer_generic_parse(struct scst_cmd *cmd,
-+ int (*nothing)(struct scst_cmd *cmd));
-+int scst_processor_generic_parse(struct scst_cmd *cmd,
-+ int (*nothing)(struct scst_cmd *cmd));
-+int scst_raid_generic_parse(struct scst_cmd *cmd,
-+ int (*nothing)(struct scst_cmd *cmd));
-+
-+int scst_block_generic_dev_done(struct scst_cmd *cmd,
-+ void (*set_block_shift)(struct scst_cmd *cmd, int block_shift));
-+int scst_tape_generic_dev_done(struct scst_cmd *cmd,
-+ void (*set_block_size)(struct scst_cmd *cmd, int block_size));
-+
-+int scst_obtain_device_parameters(struct scst_device *dev);
-+
-+void scst_reassign_persistent_sess_states(struct scst_session *new_sess,
-+ struct scst_session *old_sess);
-+
-+int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun);
-+
-+/*
-+ * Has to be put here open coded, because Linux doesn't have equivalent, which
-+ * allows exclusive wake ups of threads in LIFO order. We need it to let (yet)
-+ * unneeded threads sleep and not pollute CPU cache by their stacks.
-+ */
-+static inline void add_wait_queue_exclusive_head(wait_queue_head_t *q,
-+ wait_queue_t *wait)
-+{
-+ unsigned long flags;
-+
-+ wait->flags |= WQ_FLAG_EXCLUSIVE;
-+ spin_lock_irqsave(&q->lock, flags);
-+ __add_wait_queue(q, wait);
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+/*
-+ * Structure to match events to user space and replies on them
-+ */
-+struct scst_sysfs_user_info {
-+ /* Unique cookie to identify request */
-+ uint32_t info_cookie;
-+
-+ /* Entry in the global list */
-+ struct list_head info_list_entry;
-+
-+ /* Set if reply from the user space is being executed */
-+ unsigned int info_being_executed:1;
-+
-+ /* Set if this info is in the info_list */
-+ unsigned int info_in_list:1;
-+
-+ /* Completion to wait on for the request completion */
-+ struct completion info_completion;
-+
-+ /* Request completion status and optional data */
-+ int info_status;
-+ void *data;
-+};
-+
-+int scst_sysfs_user_add_info(struct scst_sysfs_user_info **out_info);
-+void scst_sysfs_user_del_info(struct scst_sysfs_user_info *info);
-+struct scst_sysfs_user_info *scst_sysfs_user_get_info(uint32_t cookie);
-+int scst_wait_info_completion(struct scst_sysfs_user_info *info,
-+ unsigned long timeout);
-+
-+unsigned int scst_get_setup_id(void);
-+
-+/*
-+ * Needed to avoid potential circular locking dependency between scst_mutex
-+ * and internal sysfs locking (s_active). It could be since most sysfs entries
-+ * are created and deleted under scst_mutex AND scst_mutex is taken inside
-+ * sysfs functions. So, we push from the sysfs functions all the processing
-+ * taking scst_mutex. To avoid deadlock, we return from them with EAGAIN
-+ * if processing is taking too long. User space then should poll
-+ * last_sysfs_mgmt_res until it returns the result of the processing
-+ * (something other than EAGAIN).
-+ */
-+struct scst_sysfs_work_item {
-+ /*
-+ * If true, then last_sysfs_mgmt_res will not be updated. This is
-+ * needed to allow read only sysfs monitoring during management actions.
-+ * All management actions are supposed to be externally serialized,
-+ * so then last_sysfs_mgmt_res automatically serialized too.
-+ * Otherwise a monitoring action can overwrite value of simultaneous
-+ * management action's last_sysfs_mgmt_res.
-+ */
-+ bool read_only_action;
-+
-+ struct list_head sysfs_work_list_entry;
-+ struct kref sysfs_work_kref;
-+ int (*sysfs_work_fn)(struct scst_sysfs_work_item *work);
-+ struct completion sysfs_work_done;
-+ char *buf;
-+
-+ union {
-+ struct scst_dev_type *devt;
-+ struct scst_tgt_template *tgtt;
-+ struct {
-+ struct scst_tgt *tgt;
-+ struct scst_acg *acg;
-+ union {
-+ bool is_tgt_kobj;
-+ int io_grouping_type;
-+ bool enable;
-+ cpumask_t cpu_mask;
-+ };
-+ };
-+ struct {
-+ struct scst_device *dev;
-+ int new_threads_num;
-+ enum scst_dev_type_threads_pool_type new_threads_pool_type;
-+ };
-+ struct scst_session *sess;
-+ struct {
-+ struct scst_tgt *tgt_r;
-+ unsigned long rel_tgt_id;
-+ };
-+ struct {
-+ struct kobject *kobj;
-+ };
-+ };
-+ int work_res;
-+ char *res_buf;
-+};
-+
-+int scst_alloc_sysfs_work(int (*sysfs_work_fn)(struct scst_sysfs_work_item *),
-+ bool read_only_action, struct scst_sysfs_work_item **res_work);
-+int scst_sysfs_queue_wait_work(struct scst_sysfs_work_item *work);
-+void scst_sysfs_work_get(struct scst_sysfs_work_item *work);
-+void scst_sysfs_work_put(struct scst_sysfs_work_item *work);
-+
-+char *scst_get_next_lexem(char **token_str);
-+void scst_restore_token_str(char *prev_lexem, char *token_str);
-+char *scst_get_next_token_str(char **input_str);
-+
-+void scst_init_threads(struct scst_cmd_threads *cmd_threads);
-+void scst_deinit_threads(struct scst_cmd_threads *cmd_threads);
-+
-+void scst_pass_through_cmd_done(void *data, char *sense, int result, int resid);
-+int scst_scsi_exec_async(struct scst_cmd *cmd, void *data,
-+ void (*done)(void *data, char *sense, int result, int resid));
-+
-+#endif /* __SCST_H */
-diff -uprN orig/linux-3.2/include/scst/scst_const.h linux-3.2/include/scst/scst_const.h
---- orig/linux-3.2/include/scst/scst_const.h
-+++ linux-3.2/include/scst/scst_const.h
-@@ -0,0 +1,487 @@
-+/*
-+ * include/scst_const.h
-+ *
-+ * Copyright (C) 2004 - 2011 Vladislav Bolkhovitin <vst@vlnb.net>
-+ * Copyright (C) 2007 - 2010 ID7 Ltd.
-+ * Copyright (C) 2010 - 2011 SCST Ltd.
-+ *
-+ * Contains common SCST constants.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation, version 2
-+ * of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef __SCST_CONST_H
-+#define __SCST_CONST_H
-+
-+#ifndef GENERATING_UPSTREAM_PATCH
-+/*
-+ * Include <linux/version.h> only when not converting this header file into
-+ * a patch for upstream review because only then the symbol LINUX_VERSION_CODE
-+ * is needed.
-+ */
-+#include <linux/version.h>
-+#endif
-+#include <scsi/scsi.h>
-+
-+/*
-+ * Version numbers, the same as for the kernel.
-+ *
-+ * Changing it don't forget to change SCST_FIO_REV in scst_vdisk.c
-+ * 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(2, 2, 0, 0)
-+#define SCST_VERSION_STRING_SUFFIX
-+#define SCST_VERSION_NAME "2.2.0"
-+#define SCST_VERSION_STRING SCST_VERSION_NAME SCST_VERSION_STRING_SUFFIX
-+
-+#define SCST_CONST_VERSION "$Revision: 3987 $"
-+
-+/*** Shared constants between user and kernel spaces ***/
-+
-+/* Max size of CDB */
-+#define SCST_MAX_CDB_SIZE 16
-+
-+/* Max size of long CDB */
-+#define SCST_MAX_LONG_CDB_SIZE 65536
-+
-+/* Max size of various names */
-+#define SCST_MAX_NAME 50
-+
-+/* Max size of external names, like initiator name */
-+#define SCST_MAX_EXTERNAL_NAME 256
-+
-+/* Max LUN. 2 bits are used for addressing method. */
-+#define SCST_MAX_LUN ((1 << (16-2)) - 1)
-+
-+/*
-+ * Size of sense sufficient to carry standard sense data.
-+ * Warning! It's allocated on stack!
-+ */
-+#define SCST_STANDARD_SENSE_LEN 18
-+
-+/* Max size of sense */
-+#define SCST_SENSE_BUFFERSIZE 96
-+
-+/*************************************************************
-+ ** Allowed delivery statuses for cmd's delivery_status
-+ *************************************************************/
-+
-+#define SCST_CMD_DELIVERY_SUCCESS 0
-+#define SCST_CMD_DELIVERY_FAILED -1
-+#define SCST_CMD_DELIVERY_ABORTED -2
-+
-+/*************************************************************
-+ ** Values for task management functions
-+ *************************************************************/
-+#define SCST_ABORT_TASK 0
-+#define SCST_ABORT_TASK_SET 1
-+#define SCST_CLEAR_ACA 2
-+#define SCST_CLEAR_TASK_SET 3
-+#define SCST_LUN_RESET 4
-+#define SCST_TARGET_RESET 5
-+
-+/** SCST extensions **/
-+
-+/*
-+ * Notifies about I_T nexus loss event in the corresponding session.
-+ * Aborts all tasks there, resets the reservation, if any, and sets
-+ * up the I_T Nexus loss UA.
-+ */
-+#define SCST_NEXUS_LOSS_SESS 6
-+
-+/* Aborts all tasks in the corresponding session */
-+#define SCST_ABORT_ALL_TASKS_SESS 7
-+
-+/*
-+ * Notifies about I_T nexus loss event. Aborts all tasks in all sessions
-+ * of the tgt, resets the reservations, if any, and sets up the I_T Nexus
-+ * loss UA.
-+ */
-+#define SCST_NEXUS_LOSS 8
-+
-+/* Aborts all tasks in all sessions of the tgt */
-+#define SCST_ABORT_ALL_TASKS 9
-+
-+/*
-+ * Internal TM command issued by SCST in scst_unregister_session(). It is the
-+ * same as SCST_NEXUS_LOSS_SESS, except:
-+ * - it doesn't call task_mgmt_affected_cmds_done()
-+ * - it doesn't call task_mgmt_fn_done()
-+ * - it doesn't queue NEXUS LOSS UA.
-+ *
-+ * Target drivers must NEVER use it!!
-+ */
-+#define SCST_UNREG_SESS_TM 10
-+
-+/*
-+ * Internal TM command issued by SCST in scst_pr_abort_reg(). It aborts all
-+ * tasks from mcmd->origin_pr_cmd->tgt_dev, except mcmd->origin_pr_cmd.
-+ * Additionally:
-+ * - it signals pr_aborting_cmpl completion when all affected
-+ * commands marked as aborted.
-+ * - it doesn't call task_mgmt_affected_cmds_done()
-+ * - it doesn't call task_mgmt_fn_done()
-+ * - it calls mcmd->origin_pr_cmd->scst_cmd_done() when all affected
-+ * commands aborted.
-+ *
-+ * Target drivers must NEVER use it!!
-+ */
-+#define SCST_PR_ABORT_ALL 11
-+
-+/*************************************************************
-+ ** Values for mgmt cmd's status field. Codes taken from iSCSI
-+ *************************************************************/
-+#define SCST_MGMT_STATUS_SUCCESS 0
-+#define SCST_MGMT_STATUS_TASK_NOT_EXIST -1
-+#define SCST_MGMT_STATUS_LUN_NOT_EXIST -2
-+#define SCST_MGMT_STATUS_FN_NOT_SUPPORTED -5
-+#define SCST_MGMT_STATUS_REJECTED -255
-+#define SCST_MGMT_STATUS_FAILED -129
-+
-+/*************************************************************
-+ ** SCSI LUN addressing methods. See also SAM-2 and the
-+ ** section about eight byte LUNs.
-+ *************************************************************/
-+enum scst_lun_addr_method {
-+ SCST_LUN_ADDR_METHOD_PERIPHERAL = 0,
-+ SCST_LUN_ADDR_METHOD_FLAT = 1,
-+ SCST_LUN_ADDR_METHOD_LUN = 2,
-+ SCST_LUN_ADDR_METHOD_EXTENDED_LUN = 3,
-+};
-+
-+/*************************************************************
-+ ** SCSI task attribute queue types
-+ *************************************************************/
-+enum scst_cmd_queue_type {
-+ SCST_CMD_QUEUE_UNTAGGED = 0,
-+ SCST_CMD_QUEUE_SIMPLE,
-+ SCST_CMD_QUEUE_ORDERED,
-+ SCST_CMD_QUEUE_HEAD_OF_QUEUE,
-+ SCST_CMD_QUEUE_ACA
-+};
-+
-+/*************************************************************
-+ ** CDB flags
-+ *************************************************************/
-+enum scst_cdb_flags {
-+ SCST_TRANSFER_LEN_TYPE_FIXED = 0x0001,
-+ SCST_SMALL_TIMEOUT = 0x0002,
-+ SCST_LONG_TIMEOUT = 0x0004,
-+ SCST_UNKNOWN_LENGTH = 0x0008,
-+ SCST_INFO_VALID = 0x0010, /* must be single bit */
-+ SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED = 0x0020,
-+ SCST_IMPLICIT_HQ = 0x0040,
-+ SCST_SKIP_UA = 0x0080,
-+ SCST_WRITE_MEDIUM = 0x0100,
-+ SCST_LOCAL_CMD = 0x0200,
-+ SCST_FULLY_LOCAL_CMD = 0x0400,
-+ SCST_REG_RESERVE_ALLOWED = 0x0800,
-+ SCST_WRITE_EXCL_ALLOWED = 0x1000,
-+ SCST_EXCL_ACCESS_ALLOWED = 0x2000,
-+#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
-+ SCST_TEST_IO_IN_SIRQ_ALLOWED = 0x4000,
-+#endif
-+ SCST_SERIALIZED = 0x8000,
-+ SCST_STRICTLY_SERIALIZED = 0x10000|SCST_SERIALIZED,
-+};
-+
-+/*************************************************************
-+ ** Data direction aliases. Changing it don't forget to change
-+ ** scst_to_tgt_dma_dir and SCST_DATA_DIR_MAX as well!!
-+ *************************************************************/
-+#define SCST_DATA_UNKNOWN 0
-+#define SCST_DATA_WRITE 1
-+#define SCST_DATA_READ 2
-+#define SCST_DATA_BIDI (SCST_DATA_WRITE | SCST_DATA_READ)
-+#define SCST_DATA_NONE 4
-+
-+#define SCST_DATA_DIR_MAX (SCST_DATA_NONE+1)
-+
-+/*************************************************************
-+ ** Default suffix for targets with NULL names
-+ *************************************************************/
-+#define SCST_DEFAULT_TGT_NAME_SUFFIX "_target_"
-+
-+/*************************************************************
-+ ** Sense manipulation and examination
-+ *************************************************************/
-+#define SCST_LOAD_SENSE(key_asc_ascq) key_asc_ascq
-+
-+#define SCST_SENSE_VALID(sense) ((sense != NULL) && \
-+ ((((const uint8_t *)(sense))[0] & 0x70) == 0x70))
-+
-+#define SCST_NO_SENSE(sense) ((sense != NULL) && \
-+ (((const uint8_t *)(sense))[2] == 0))
-+
-+/*************************************************************
-+ ** Sense data for the appropriate errors. Can be used with
-+ ** scst_set_cmd_error()
-+ *************************************************************/
-+#define scst_sense_no_sense NO_SENSE, 0x00, 0
-+#define scst_sense_hardw_error HARDWARE_ERROR, 0x44, 0
-+#define scst_sense_aborted_command ABORTED_COMMAND, 0x00, 0
-+#define scst_sense_invalid_opcode ILLEGAL_REQUEST, 0x20, 0
-+#define scst_sense_invalid_field_in_cdb ILLEGAL_REQUEST, 0x24, 0
-+#define scst_sense_invalid_field_in_parm_list ILLEGAL_REQUEST, 0x26, 0
-+#define scst_sense_parameter_value_invalid ILLEGAL_REQUEST, 0x26, 2
-+#define scst_sense_invalid_release ILLEGAL_REQUEST, 0x26, 4
-+#define scst_sense_parameter_list_length_invalid \
-+ ILLEGAL_REQUEST, 0x1A, 0
-+#define scst_sense_reset_UA UNIT_ATTENTION, 0x29, 0
-+#define scst_sense_nexus_loss_UA UNIT_ATTENTION, 0x29, 0x7
-+#define scst_sense_saving_params_unsup ILLEGAL_REQUEST, 0x39, 0
-+#define scst_sense_lun_not_supported ILLEGAL_REQUEST, 0x25, 0
-+#define scst_sense_data_protect DATA_PROTECT, 0x00, 0
-+#define scst_sense_miscompare_error MISCOMPARE, 0x1D, 0
-+#define scst_sense_block_out_range_error ILLEGAL_REQUEST, 0x21, 0
-+#define scst_sense_medium_changed_UA UNIT_ATTENTION, 0x28, 0
-+#define scst_sense_read_error MEDIUM_ERROR, 0x11, 0
-+#define scst_sense_write_error MEDIUM_ERROR, 0x03, 0
-+#define scst_sense_not_ready NOT_READY, 0x04, 0x10
-+#define scst_sense_invalid_message ILLEGAL_REQUEST, 0x49, 0
-+#define scst_sense_cleared_by_another_ini_UA UNIT_ATTENTION, 0x2F, 0
-+#define scst_sense_capacity_data_changed UNIT_ATTENTION, 0x2A, 0x9
-+#define scst_sense_reservation_preempted UNIT_ATTENTION, 0x2A, 0x03
-+#define scst_sense_reservation_released UNIT_ATTENTION, 0x2A, 0x04
-+#define scst_sense_registrations_preempted UNIT_ATTENTION, 0x2A, 0x05
-+#define scst_sense_asym_access_state_changed UNIT_ATTENTION, 0x2A, 0x06
-+#define scst_sense_reported_luns_data_changed UNIT_ATTENTION, 0x3F, 0xE
-+#define scst_sense_inquery_data_changed UNIT_ATTENTION, 0x3F, 0x3
-+
-+/*************************************************************
-+ * SCSI opcodes not listed anywhere else
-+ *************************************************************/
-+#define INIT_ELEMENT_STATUS 0x07
-+#define INIT_ELEMENT_STATUS_RANGE 0x37
-+#define PREVENT_ALLOW_MEDIUM 0x1E
-+#define REQUEST_VOLUME_ADDRESS 0xB5
-+#define WRITE_VERIFY_16 0x8E
-+#define VERIFY_6 0x13
-+#ifndef VERIFY_12
-+#define VERIFY_12 0xAF
-+#endif
-+#ifndef GENERATING_UPSTREAM_PATCH
-+/*
-+ * The constants below have been defined in the kernel header <scsi/scsi.h>
-+ * and hence are not needed when this header file is included in kernel code.
-+ * The definitions below are only used when this header file is included during
-+ * compilation of SCST's user space components.
-+ */
-+#ifndef READ_16
-+#define READ_16 0x88
-+#endif
-+#ifndef WRITE_16
-+#define WRITE_16 0x8a
-+#endif
-+#ifndef VERIFY_16
-+#define VERIFY_16 0x8f
-+#endif
-+#ifndef SERVICE_ACTION_IN
-+#define SERVICE_ACTION_IN 0x9e
-+#endif
-+#ifndef SAI_READ_CAPACITY_16
-+/* values for service action in */
-+#define SAI_READ_CAPACITY_16 0x10
-+#endif
-+#endif
-+#ifndef GENERATING_UPSTREAM_PATCH
-+#ifndef REPORT_LUNS
-+#define REPORT_LUNS 0xa0
-+#endif
-+#endif
-+
-+
-+/*************************************************************
-+ ** SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
-+ ** T10/1561-D Revision 4 Draft dated 7th November 2002.
-+ *************************************************************/
-+#define SAM_STAT_GOOD 0x00
-+#define SAM_STAT_CHECK_CONDITION 0x02
-+#define SAM_STAT_CONDITION_MET 0x04
-+#define SAM_STAT_BUSY 0x08
-+#define SAM_STAT_INTERMEDIATE 0x10
-+#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14
-+#define SAM_STAT_RESERVATION_CONFLICT 0x18
-+#define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */
-+#define SAM_STAT_TASK_SET_FULL 0x28
-+#define SAM_STAT_ACA_ACTIVE 0x30
-+#define SAM_STAT_TASK_ABORTED 0x40
-+
-+/*************************************************************
-+ ** Control byte field in CDB
-+ *************************************************************/
-+#define CONTROL_BYTE_LINK_BIT 0x01
-+#define CONTROL_BYTE_NACA_BIT 0x04
-+
-+/*************************************************************
-+ ** Byte 1 in INQUIRY CDB
-+ *************************************************************/
-+#define SCST_INQ_EVPD 0x01
-+
-+/*************************************************************
-+ ** Byte 3 in Standard INQUIRY data
-+ *************************************************************/
-+#define SCST_INQ_BYTE3 3
-+
-+#define SCST_INQ_NORMACA_BIT 0x20
-+
-+/*************************************************************
-+ ** TPGS field in byte 5 of the INQUIRY response (SPC-4).
-+ *************************************************************/
-+enum {
-+ SCST_INQ_TPGS_MODE_IMPLICIT = 0x10,
-+ SCST_INQ_TPGS_MODE_EXPLICIT = 0x20,
-+};
-+
-+/*************************************************************
-+ ** Byte 2 in RESERVE_10 CDB
-+ *************************************************************/
-+#define SCST_RES_3RDPTY 0x10
-+#define SCST_RES_LONGID 0x02
-+
-+/*************************************************************
-+ ** Values for the control mode page TST field
-+ *************************************************************/
-+#define SCST_CONTR_MODE_ONE_TASK_SET 0
-+#define SCST_CONTR_MODE_SEP_TASK_SETS 1
-+
-+/*******************************************************************
-+ ** Values for the control mode page QUEUE ALGORITHM MODIFIER field
-+ *******************************************************************/
-+#define SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER 0
-+#define SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER 1
-+
-+/*************************************************************
-+ ** Values for the control mode page D_SENSE field
-+ *************************************************************/
-+#define SCST_CONTR_MODE_FIXED_SENSE 0
-+#define SCST_CONTR_MODE_DESCR_SENSE 1
-+
-+/*************************************************************
-+ ** TransportID protocol identifiers
-+ *************************************************************/
-+
-+#define SCSI_TRANSPORTID_PROTOCOLID_FCP2 0
-+#define SCSI_TRANSPORTID_PROTOCOLID_SPI5 1
-+#define SCSI_TRANSPORTID_PROTOCOLID_SRP 4
-+#define SCSI_TRANSPORTID_PROTOCOLID_ISCSI 5
-+#define SCSI_TRANSPORTID_PROTOCOLID_SAS 6
-+
-+/**
-+ * enum scst_tg_state - SCSI target port group asymmetric access state.
-+ *
-+ * See also the documentation of the REPORT TARGET PORT GROUPS command in SPC-4.
-+ */
-+enum scst_tg_state {
-+ SCST_TG_STATE_OPTIMIZED = 0x0,
-+ SCST_TG_STATE_NONOPTIMIZED = 0x1,
-+ SCST_TG_STATE_STANDBY = 0x2,
-+ SCST_TG_STATE_UNAVAILABLE = 0x3,
-+ SCST_TG_STATE_LBA_DEPENDENT = 0x4,
-+ SCST_TG_STATE_OFFLINE = 0xe,
-+ SCST_TG_STATE_TRANSITIONING = 0xf,
-+};
-+
-+/**
-+ * Target port group preferred bit.
-+ *
-+ * See also the documentation of the REPORT TARGET PORT GROUPS command in SPC-4.
-+ */
-+enum {
-+ SCST_TG_PREFERRED = 0x80,
-+};
-+
-+/**
-+ * enum scst_tg_sup - Supported SCSI target port group states.
-+ *
-+ * See also the documentation of the REPORT TARGET PORT GROUPS command in SPC-4.
-+ */
-+enum scst_tg_sup {
-+ SCST_TG_SUP_OPTIMIZED = 0x01,
-+ SCST_TG_SUP_NONOPTIMIZED = 0x02,
-+ SCST_TG_SUP_STANDBY = 0x04,
-+ SCST_TG_SUP_UNAVAILABLE = 0x08,
-+ SCST_TG_SUP_LBA_DEPENDENT = 0x10,
-+ SCST_TG_SUP_OFFLINE = 0x40,
-+ SCST_TG_SUP_TRANSITION = 0x80,
-+};
-+
-+/*************************************************************
-+ ** Misc SCSI constants
-+ *************************************************************/
-+#define SCST_SENSE_ASC_UA_RESET 0x29
-+#define BYTCHK 0x02
-+#define POSITION_LEN_SHORT 20
-+#define POSITION_LEN_LONG 32
-+
-+/*************************************************************
-+ ** Various timeouts
-+ *************************************************************/
-+#define SCST_DEFAULT_TIMEOUT (60 * HZ)
-+
-+#define SCST_GENERIC_CHANGER_TIMEOUT (3 * HZ)
-+#define SCST_GENERIC_CHANGER_LONG_TIMEOUT (14000 * HZ)
-+
-+#define SCST_GENERIC_PROCESSOR_TIMEOUT (3 * HZ)
-+#define SCST_GENERIC_PROCESSOR_LONG_TIMEOUT (14000 * HZ)
-+
-+#define SCST_GENERIC_TAPE_SMALL_TIMEOUT (3 * HZ)
-+#define SCST_GENERIC_TAPE_REG_TIMEOUT (900 * HZ)
-+#define SCST_GENERIC_TAPE_LONG_TIMEOUT (14000 * HZ)
-+
-+#define SCST_GENERIC_MODISK_SMALL_TIMEOUT (3 * HZ)
-+#define SCST_GENERIC_MODISK_REG_TIMEOUT (900 * HZ)
-+#define SCST_GENERIC_MODISK_LONG_TIMEOUT (14000 * HZ)
-+
-+#define SCST_GENERIC_DISK_SMALL_TIMEOUT (3 * HZ)
-+#define SCST_GENERIC_DISK_REG_TIMEOUT (60 * HZ)
-+#define SCST_GENERIC_DISK_LONG_TIMEOUT (3600 * HZ)
-+
-+#define SCST_GENERIC_RAID_TIMEOUT (3 * HZ)
-+#define SCST_GENERIC_RAID_LONG_TIMEOUT (14000 * HZ)
-+
-+#define SCST_GENERIC_CDROM_SMALL_TIMEOUT (3 * HZ)
-+#define SCST_GENERIC_CDROM_REG_TIMEOUT (900 * HZ)
-+#define SCST_GENERIC_CDROM_LONG_TIMEOUT (14000 * HZ)
-+
-+#define SCST_MAX_OTHER_TIMEOUT (14000 * HZ)
-+
-+/*************************************************************
-+ ** I/O grouping attribute string values. Must match constants
-+ ** w/o '_STR' suffix!
-+ *************************************************************/
-+#define SCST_IO_GROUPING_AUTO_STR "auto"
-+#define SCST_IO_GROUPING_THIS_GROUP_ONLY_STR "this_group_only"
-+#define SCST_IO_GROUPING_NEVER_STR "never"
-+
-+/*************************************************************
-+ ** Threads pool type attribute string values.
-+ ** Must match scst_dev_type_threads_pool_type!
-+ *************************************************************/
-+#define SCST_THREADS_POOL_PER_INITIATOR_STR "per_initiator"
-+#define SCST_THREADS_POOL_SHARED_STR "shared"
-+
-+/*************************************************************
-+ ** Misc constants
-+ *************************************************************/
-+#define SCST_SYSFS_BLOCK_SIZE PAGE_SIZE
-+
-+#define SCST_PR_DIR "/var/lib/scst/pr"
-+
-+#define TID_COMMON_SIZE 24
-+
-+#define SCST_SYSFS_KEY_MARK "[key]"
-+
-+#define SCST_MIN_REL_TGT_ID 1
-+#define SCST_MAX_REL_TGT_ID 65535
-+
-+#endif /* __SCST_CONST_H */
-diff -uprN orig/linux-3.2/drivers/scst/scst_main.c linux-3.2/drivers/scst/scst_main.c
---- orig/linux-3.2/drivers/scst/scst_main.c
-+++ linux-3.2/drivers/scst/scst_main.c
-@@ -0,0 +1,2229 @@
-+/*
-+ * scst_main.c
-+ *
-+ * Copyright (C) 2004 - 2011 Vladislav Bolkhovitin <vst@vlnb.net>
-+ * Copyright (C) 2004 - 2005 Leonid Stoljar
-+ * Copyright (C) 2007 - 2010 ID7 Ltd.
-+ * Copyright (C) 2010 - 2011 SCST Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation, version 2
-+ * of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/module.h>
-+
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/list.h>
-+#include <linux/spinlock.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/unistd.h>
-+#include <linux/string.h>
-+#include <linux/kthread.h>
-+#include <linux/delay.h>
-+#include <linux/lockdep.h>
-+
-+#include <scst/scst.h>
-+#include "scst_priv.h"
-+#include "scst_mem.h"
-+#include "scst_pres.h"
-+
-+#if defined(CONFIG_HIGHMEM4G) || defined(CONFIG_HIGHMEM64G)
-+#warning HIGHMEM kernel configurations are fully supported, but not \
-+recommended for performance reasons. Consider changing VMSPLIT \
-+option or use a 64-bit configuration instead. See README file for \
-+details.
-+#endif
-+
-+/**
-+ ** SCST global variables. They are all uninitialized to have their layout in
-+ ** memory be exactly as specified. Otherwise compiler puts zero-initialized
-+ ** variable separately from nonzero-initialized ones.
-+ **/
-+
-+/*
-+ * Main SCST mutex. All targets, devices and dev_types management is done
-+ * under this mutex.
-+ *
-+ * It must NOT be used in any works (schedule_work(), etc.), because
-+ * otherwise a deadlock (double lock, actually) is possible, e.g., with
-+ * scst_user detach_tgt(), which is called under scst_mutex and calls
-+ * flush_scheduled_work().
-+ */
-+struct mutex scst_mutex;
-+EXPORT_SYMBOL_GPL(scst_mutex);
-+
-+/*
-+ * Secondary level main mutex, inner for scst_mutex. Needed for
-+ * __scst_pr_register_all_tg_pt(), since we can't use scst_mutex there,
-+ * because of the circular locking dependency with dev_pr_mutex.
-+ */
-+struct mutex scst_mutex2;
-+
-+/* Both protected by scst_mutex or scst_mutex2 on read and both on write */
-+struct list_head scst_template_list;
-+struct list_head scst_dev_list;
-+
-+/* Protected by scst_mutex */
-+struct list_head scst_dev_type_list;
-+struct list_head scst_virtual_dev_type_list;
-+
-+spinlock_t scst_main_lock;
-+
-+static struct kmem_cache *scst_mgmt_cachep;
-+mempool_t *scst_mgmt_mempool;
-+static struct kmem_cache *scst_mgmt_stub_cachep;
-+mempool_t *scst_mgmt_stub_mempool;
-+static struct kmem_cache *scst_ua_cachep;
-+mempool_t *scst_ua_mempool;
-+static struct kmem_cache *scst_sense_cachep;
-+mempool_t *scst_sense_mempool;
-+static struct kmem_cache *scst_aen_cachep;
-+mempool_t *scst_aen_mempool;
-+struct kmem_cache *scst_tgtd_cachep;
-+struct kmem_cache *scst_sess_cachep;
-+struct kmem_cache *scst_acgd_cachep;
-+
-+unsigned int scst_setup_id;
-+
-+spinlock_t scst_init_lock;
-+wait_queue_head_t scst_init_cmd_list_waitQ;
-+struct list_head scst_init_cmd_list;
-+unsigned int scst_init_poll_cnt;
-+
-+struct kmem_cache *scst_cmd_cachep;
-+
-+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
-+unsigned long scst_trace_flag;
-+#endif
-+
-+int scst_max_tasklet_cmd = SCST_DEF_MAX_TASKLET_CMD;
-+
-+unsigned long scst_flags;
-+
-+struct scst_cmd_threads scst_main_cmd_threads;
-+
-+struct scst_percpu_info scst_percpu_infos[NR_CPUS];
-+
-+spinlock_t scst_mcmd_lock;
-+struct list_head scst_active_mgmt_cmd_list;
-+struct list_head scst_delayed_mgmt_cmd_list;
-+wait_queue_head_t scst_mgmt_cmd_list_waitQ;
-+
-+wait_queue_head_t scst_mgmt_waitQ;
-+spinlock_t scst_mgmt_lock;
-+struct list_head scst_sess_init_list;
-+struct list_head scst_sess_shut_list;
-+
-+wait_queue_head_t scst_dev_cmd_waitQ;
-+
-+#ifdef CONFIG_LOCKDEP
-+static struct lock_class_key scst_suspend_key;
-+struct lockdep_map scst_suspend_dep_map =
-+ STATIC_LOCKDEP_MAP_INIT("scst_suspend_activity", &scst_suspend_key);
-+#endif
-+static struct mutex scst_suspend_mutex;
-+/* protected by scst_suspend_mutex */
-+static struct list_head scst_cmd_threads_list;
-+
-+int scst_threads;
-+static struct task_struct *scst_init_cmd_thread;
-+static struct task_struct *scst_mgmt_thread;
-+static struct task_struct *scst_mgmt_cmd_thread;
-+
-+static int suspend_count;
-+
-+static int scst_virt_dev_last_id; /* protected by scst_mutex */
-+
-+cpumask_t default_cpu_mask;
-+
-+static unsigned int scst_max_cmd_mem;
-+unsigned int scst_max_dev_cmd_mem;
-+
-+module_param_named(scst_threads, scst_threads, int, 0);
-+MODULE_PARM_DESC(scst_threads, "SCSI target threads count");
-+
-+module_param_named(scst_max_cmd_mem, scst_max_cmd_mem, int, S_IRUGO);
-+MODULE_PARM_DESC(scst_max_cmd_mem, "Maximum memory allowed to be consumed by "
-+ "all SCSI commands of all devices at any given time in MB");
-+
-+module_param_named(scst_max_dev_cmd_mem, scst_max_dev_cmd_mem, int, S_IRUGO);
-+MODULE_PARM_DESC(scst_max_dev_cmd_mem, "Maximum memory allowed to be consumed "
-+ "by all SCSI commands of a device at any given time in MB");
-+
-+struct scst_dev_type scst_null_devtype = {
-+ .name = "none",
-+ .threads_num = -1,
-+};
-+
-+static void __scst_resume_activity(void);
-+
-+/**
-+ * __scst_register_target_template() - register target template.
-+ * @vtt: target template
-+ * @version: SCST_INTERFACE_VERSION version string to ensure that
-+ * SCST core and the target driver use the same version of
-+ * the SCST interface
-+ *
-+ * Description:
-+ * Registers a target template and returns 0 on success or appropriate
-+ * error code otherwise.
-+ *
-+ * Target drivers supposed to behave sanely and not call register()
-+ * and unregister() randomly simultaneously.
-+ */
-+int __scst_register_target_template(struct scst_tgt_template *vtt,
-+ const char *version)
-+{
-+ int res = 0;
-+ struct scst_tgt_template *t;
-+
-+ TRACE_ENTRY();
-+
-+ INIT_LIST_HEAD(&vtt->tgt_list);
-+
-+ if (strcmp(version, SCST_INTERFACE_VERSION) != 0) {
-+ PRINT_ERROR("Incorrect version of target %s", vtt->name);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ if (!vtt->detect) {
-+ PRINT_ERROR("Target driver %s must have "
-+ "detect() method.", vtt->name);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ if (!vtt->release) {
-+ PRINT_ERROR("Target driver %s must have "
-+ "release() method.", vtt->name);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ if (!vtt->xmit_response) {
-+ PRINT_ERROR("Target driver %s must have "
-+ "xmit_response() method.", vtt->name);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ if (vtt->get_initiator_port_transport_id == NULL)
-+ PRINT_WARNING("Target driver %s doesn't support Persistent "
-+ "Reservations", vtt->name);
-+
-+ if (vtt->threads_num < 0) {
-+ PRINT_ERROR("Wrong threads_num value %d for "
-+ "target \"%s\"", vtt->threads_num,
-+ vtt->name);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ if ((!vtt->enable_target || !vtt->is_target_enabled) &&
-+ !vtt->enabled_attr_not_needed)
-+ PRINT_WARNING("Target driver %s doesn't have enable_target() "
-+ "and/or is_target_enabled() method(s). This is unsafe "
-+ "and can lead that initiators connected on the "
-+ "initialization time can see an unexpected set of "
-+ "devices or no devices at all!", vtt->name);
-+
-+ if (((vtt->add_target != NULL) && (vtt->del_target == NULL)) ||
-+ ((vtt->add_target == NULL) && (vtt->del_target != NULL))) {
-+ PRINT_ERROR("Target driver %s must either define both "
-+ "add_target() and del_target(), or none.", vtt->name);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ if (vtt->rdy_to_xfer == NULL)
-+ vtt->rdy_to_xfer_atomic = 1;
-+
-+ res = mutex_lock_interruptible(&scst_mutex);
-+ if (res != 0)
-+ goto out;
-+ list_for_each_entry(t, &scst_template_list, scst_template_list_entry) {
-+ if (strcmp(t->name, vtt->name) == 0) {
-+ PRINT_ERROR("Target driver %s already registered",
-+ vtt->name);
-+ mutex_unlock(&scst_mutex);
-+ goto out_unlock;
-+ }
-+ }
-+ mutex_unlock(&scst_mutex);
-+
-+ res = scst_tgtt_sysfs_create(vtt);
-+ if (res != 0)
-+ goto out;
-+
-+ mutex_lock(&scst_mutex);
-+ mutex_lock(&scst_mutex2);
-+ list_add_tail(&vtt->scst_template_list_entry, &scst_template_list);
-+ mutex_unlock(&scst_mutex2);
-+ mutex_unlock(&scst_mutex);
-+
-+ TRACE_DBG("%s", "Calling target driver's detect()");
-+ res = vtt->detect(vtt);
-+ TRACE_DBG("Target driver's detect() returned %d", res);
-+ if (res < 0) {
-+ PRINT_ERROR("%s", "The detect() routine failed");
-+ res = -EINVAL;
-+ goto out_del;
-+ }
-+
-+ PRINT_INFO("Target template %s registered successfully", vtt->name);
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_del:
-+ scst_tgtt_sysfs_del(vtt);
-+
-+ mutex_lock(&scst_mutex);
-+
-+ mutex_lock(&scst_mutex2);
-+ list_del(&vtt->scst_template_list_entry);
-+ mutex_unlock(&scst_mutex2);
-+
-+out_unlock:
-+ mutex_unlock(&scst_mutex);
-+ goto out;
-+}
-+EXPORT_SYMBOL_GPL(__scst_register_target_template);
-+
-+static int scst_check_non_gpl_target_template(struct scst_tgt_template *vtt)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ if (vtt->task_mgmt_affected_cmds_done || vtt->threads_num ||
-+ vtt->on_hw_pending_cmd_timeout) {
-+ PRINT_ERROR("Not allowed functionality in non-GPL version for "
-+ "target template %s", vtt->name);
-+ res = -EPERM;
-+ goto out;
-+ }
-+
-+ res = 0;
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/**
-+ * __scst_register_target_template_non_gpl() - register target template,
-+ * non-GPL version
-+ * @vtt: target template
-+ * @version: SCST_INTERFACE_VERSION version string to ensure that
-+ * SCST core and the target driver use the same version of
-+ * the SCST interface
-+ *
-+ * Description:
-+ * Registers a target template and returns 0 on success or appropriate
-+ * error code otherwise.
-+ *
-+ * Note: *vtt must be static!
-+ */
-+int __scst_register_target_template_non_gpl(struct scst_tgt_template *vtt,
-+ const char *version)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ res = scst_check_non_gpl_target_template(vtt);
-+ if (res != 0)
-+ goto out;
-+
-+ res = __scst_register_target_template(vtt, version);
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+EXPORT_SYMBOL(__scst_register_target_template_non_gpl);
-+
-+/**
-+ * scst_unregister_target_template() - unregister target template
-+ *
-+ * Target drivers supposed to behave sanely and not call register()
-+ * and unregister() randomly simultaneously. Also it is supposed that
-+ * no attempts to create new targets for this vtt will be done in a race
-+ * with this function.
-+ */
-+void scst_unregister_target_template(struct scst_tgt_template *vtt)
-+{
-+ struct scst_tgt *tgt;
-+ struct scst_tgt_template *t;
-+ int found = 0;
-+
-+ TRACE_ENTRY();
-+
-+ mutex_lock(&scst_mutex);
-+
-+ list_for_each_entry(t, &scst_template_list, scst_template_list_entry) {
-+ if (strcmp(t->name, vtt->name) == 0) {
-+ found = 1;
-+ break;
-+ }
-+ }
-+ if (!found) {
-+ PRINT_ERROR("Target driver %s isn't registered", vtt->name);
-+ goto out_err_up;
-+ }
-+
-+ mutex_lock(&scst_mutex2);
-+ list_del(&vtt->scst_template_list_entry);
-+ mutex_unlock(&scst_mutex2);
-+
-+ /* Wait for outstanding sysfs mgmt calls completed */
-+ while (vtt->tgtt_active_sysfs_works_count > 0) {
-+ mutex_unlock(&scst_mutex);
-+ msleep(100);
-+ mutex_lock(&scst_mutex);
-+ }
-+
-+restart:
-+ list_for_each_entry(tgt, &vtt->tgt_list, tgt_list_entry) {
-+ mutex_unlock(&scst_mutex);
-+ scst_unregister_target(tgt);
-+ mutex_lock(&scst_mutex);
-+ goto restart;
-+ }
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ scst_tgtt_sysfs_del(vtt);
-+
-+ PRINT_INFO("Target template %s unregistered successfully", vtt->name);
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+
-+out_err_up:
-+ mutex_unlock(&scst_mutex);
-+ goto out;
-+}
-+EXPORT_SYMBOL(scst_unregister_target_template);
-+
-+/**
-+ * scst_register_target() - register target
-+ *
-+ * Registers a target for template vtt and returns new target structure on
-+ * success or NULL otherwise.
-+ */
-+struct scst_tgt *scst_register_target(struct scst_tgt_template *vtt,
-+ const char *target_name)
-+{
-+ struct scst_tgt *tgt, *t;
-+ int rc = 0;
-+
-+ TRACE_ENTRY();
-+
-+ rc = scst_alloc_tgt(vtt, &tgt);
-+ if (rc != 0)
-+ goto out;
-+
-+ if (target_name != NULL) {
-+
-+ tgt->tgt_name = kstrdup(target_name, GFP_KERNEL);
-+ if (tgt->tgt_name == NULL) {
-+ PRINT_ERROR("Allocation of tgt name %s failed",
-+ target_name);
-+ rc = -ENOMEM;
-+ goto out_free_tgt;
-+ }
-+ } else {
-+ static int tgt_num; /* protected by scst_mutex */
-+
-+ PRINT_WARNING("Usage of autogenerated SCST target names "
-+ "is deprecated and will be removed in one of the next "
-+ "versions. It is strongly recommended to update target "
-+ "driver %s to use hardware related persistent target "
-+ "names instead", vtt->name);
-+
-+ tgt->tgt_name = kasprintf(GFP_KERNEL, "%s%s%d", vtt->name,
-+ SCST_DEFAULT_TGT_NAME_SUFFIX, tgt_num);
-+ if (tgt->tgt_name == NULL) {
-+ PRINT_ERROR("Allocation of tgt name failed "
-+ "(template name %s)", vtt->name);
-+ rc = -ENOMEM;
-+ goto out_free_tgt;
-+ }
-+ tgt_num++;
-+ }
-+
-+ rc = mutex_lock_interruptible(&scst_mutex);
-+ if (rc != 0)
-+ goto out_free_tgt;
-+
-+ list_for_each_entry(t, &vtt->tgt_list, tgt_list_entry) {
-+ if (strcmp(t->tgt_name, tgt->tgt_name) == 0) {
-+ PRINT_ERROR("target %s already exists", tgt->tgt_name);
-+ rc = -EEXIST;
-+ goto out_unlock;
-+ }
-+ }
-+
-+ rc = scst_tgt_sysfs_create(tgt);
-+ if (rc < 0)
-+ goto out_unlock;
-+
-+ tgt->default_acg = scst_alloc_add_acg(tgt, tgt->tgt_name, false);
-+ if (tgt->default_acg == NULL)
-+ goto out_sysfs_del;
-+
-+ mutex_lock(&scst_mutex2);
-+ list_add_tail(&tgt->tgt_list_entry, &vtt->tgt_list);
-+ mutex_unlock(&scst_mutex2);
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ PRINT_INFO("Target %s for template %s registered successfully",
-+ tgt->tgt_name, vtt->name);
-+
-+ TRACE_DBG("tgt %p", tgt);
-+
-+out:
-+ TRACE_EXIT();
-+ return tgt;
-+
-+out_sysfs_del:
-+ mutex_unlock(&scst_mutex);
-+ scst_tgt_sysfs_del(tgt);
-+ goto out_free_tgt;
-+
-+out_unlock:
-+ mutex_unlock(&scst_mutex);
-+
-+out_free_tgt:
-+ /* In case of error tgt_name will be freed in scst_free_tgt() */
-+ scst_free_tgt(tgt);
-+ tgt = NULL;
-+ goto out;
-+}
-+EXPORT_SYMBOL(scst_register_target);
-+
-+static inline int test_sess_list(struct scst_tgt *tgt)
-+{
-+ int res;
-+ mutex_lock(&scst_mutex);
-+ res = list_empty(&tgt->sess_list);
-+ mutex_unlock(&scst_mutex);
-+ return res;
-+}
-+
-+/**
-+ * scst_unregister_target() - unregister target.
-+ *
-+ * It is supposed that no attempts to create new sessions for this
-+ * target will be done in a race with this function.
-+ */
-+void scst_unregister_target(struct scst_tgt *tgt)
-+{
-+ struct scst_session *sess;
-+ struct scst_tgt_template *vtt = tgt->tgtt;
-+ struct scst_acg *acg, *acg_tmp;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_DBG("%s", "Calling target driver's release()");
-+ tgt->tgtt->release(tgt);
-+ TRACE_DBG("%s", "Target driver's release() returned");
-+
-+ mutex_lock(&scst_mutex);
-+again:
-+ list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) {
-+ if (sess->shut_phase == SCST_SESS_SPH_READY) {
-+ /*
-+ * Sometimes it's hard for target driver to track all
-+ * its sessions (see scst_local, eg), so let's help it.
-+ */
-+ mutex_unlock(&scst_mutex);
-+ scst_unregister_session(sess, 0, NULL);
-+ mutex_lock(&scst_mutex);
-+ goto again;
-+ }
-+ }
-+ mutex_unlock(&scst_mutex);
-+
-+ TRACE_DBG("%s", "Waiting for sessions shutdown");
-+ wait_event(tgt->unreg_waitQ, test_sess_list(tgt));
-+ TRACE_DBG("%s", "wait_event() returned");
-+
-+ scst_suspend_activity(false);
-+ mutex_lock(&scst_mutex);
-+
-+ mutex_lock(&scst_mutex2);
-+ list_del(&tgt->tgt_list_entry);
-+ mutex_unlock(&scst_mutex2);
-+
-+ del_timer_sync(&tgt->retry_timer);
-+
-+ scst_tg_tgt_remove_by_tgt(tgt);
-+
-+ scst_del_free_acg(tgt->default_acg);
-+
-+ list_for_each_entry_safe(acg, acg_tmp, &tgt->tgt_acg_list,
-+ acg_list_entry) {
-+ scst_del_free_acg(acg);
-+ }
-+
-+ mutex_unlock(&scst_mutex);
-+ scst_resume_activity();
-+
-+ scst_tgt_sysfs_del(tgt);
-+
-+ PRINT_INFO("Target %s for template %s unregistered successfully",
-+ tgt->tgt_name, vtt->name);
-+
-+ scst_free_tgt(tgt);
-+
-+ TRACE_DBG("Unregistering tgt %p finished", tgt);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL(scst_unregister_target);
-+
-+int scst_get_cmd_counter(void)
-+{
-+ int i, res = 0;
-+ for (i = 0; i < (int)ARRAY_SIZE(scst_percpu_infos); i++)
-+ res += atomic_read(&scst_percpu_infos[i].cpu_cmd_count);
-+ return res;
-+}
-+
-+static int scst_susp_wait(bool interruptible)
-+{
-+ int res = 0;
-+
-+ TRACE_ENTRY();
-+
-+ if (interruptible) {
-+ res = wait_event_interruptible_timeout(scst_dev_cmd_waitQ,
-+ (scst_get_cmd_counter() == 0),
-+ SCST_SUSPENDING_TIMEOUT);
-+ if (res <= 0) {
-+ __scst_resume_activity();
-+ if (res == 0)
-+ res = -EBUSY;
-+ } else
-+ res = 0;
-+ } else
-+ wait_event(scst_dev_cmd_waitQ, scst_get_cmd_counter() == 0);
-+
-+ TRACE_MGMT_DBG("wait_event() returned %d", res);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/**
-+ * scst_suspend_activity() - globally suspend any activity
-+ *
-+ * Description:
-+ * Globally suspends any activity and doesn't return, until there are any
-+ * active commands (state after SCST_CMD_STATE_INIT). If "interruptible"
-+ * is true, it returns after SCST_SUSPENDING_TIMEOUT or if it was interrupted
-+ * by a signal with the corresponding error status < 0. If "interruptible"
-+ * is false, it will wait virtually forever. On success returns 0.
-+ *
-+ * New arriving commands stay in the suspended state until
-+ * scst_resume_activity() is called.
-+ */
-+int scst_suspend_activity(bool interruptible)
-+{
-+ int res = 0;
-+ bool rep = false;
-+
-+ TRACE_ENTRY();
-+
-+ rwlock_acquire_read(&scst_suspend_dep_map, 0, 0, _RET_IP_);
-+
-+ if (interruptible) {
-+ if (mutex_lock_interruptible(&scst_suspend_mutex) != 0) {
-+ res = -EINTR;
-+ goto out;
-+ }
-+ } else
-+ mutex_lock(&scst_suspend_mutex);
-+
-+ TRACE_MGMT_DBG("suspend_count %d", suspend_count);
-+ suspend_count++;
-+ if (suspend_count > 1)
-+ goto out_up;
-+
-+ set_bit(SCST_FLAG_SUSPENDING, &scst_flags);
-+ set_bit(SCST_FLAG_SUSPENDED, &scst_flags);
-+ /*
-+ * Assignment of SCST_FLAG_SUSPENDING and SCST_FLAG_SUSPENDED must be
-+ * ordered with cpu_cmd_count in scst_get(). Otherwise lockless logic in
-+ * scst_translate_lun() and scst_mgmt_translate_lun() won't work.
-+ */
-+ smp_mb__after_set_bit();
-+
-+ /*
-+ * See comment in scst_user.c::dev_user_task_mgmt_fn() for more
-+ * information about scst_user behavior.
-+ *
-+ * ToDo: make the global suspending unneeded (switch to per-device
-+ * reference counting? That would mean to switch off from lockless
-+ * implementation of scst_translate_lun().. )
-+ */
-+
-+ if (scst_get_cmd_counter() != 0) {
-+ PRINT_INFO("Waiting for %d active commands to complete... This "
-+ "might take few minutes for disks or few hours for "
-+ "tapes, if you use long executed commands, like "
-+ "REWIND or FORMAT. In case, if you have a hung user "
-+ "space device (i.e. made using scst_user module) not "
-+ "responding to any commands, if might take virtually "
-+ "forever until the corresponding user space "
-+ "program recovers and starts responding or gets "
-+ "killed.", scst_get_cmd_counter());
-+ rep = true;
-+
-+ lock_contended(&scst_suspend_dep_map, _RET_IP_);
-+ }
-+
-+ res = scst_susp_wait(interruptible);
-+ if (res != 0)
-+ goto out_clear;
-+
-+ clear_bit(SCST_FLAG_SUSPENDING, &scst_flags);
-+ /* See comment about smp_mb() above */
-+ smp_mb__after_clear_bit();
-+
-+ TRACE_MGMT_DBG("Waiting for %d active commands finally to complete",
-+ scst_get_cmd_counter());
-+
-+ res = scst_susp_wait(interruptible);
-+ if (res != 0)
-+ goto out_clear;
-+
-+ if (rep)
-+ PRINT_INFO("%s", "All active commands completed");
-+
-+out_up:
-+ mutex_unlock(&scst_suspend_mutex);
-+
-+out:
-+ if (res == 0)
-+ lock_acquired(&scst_suspend_dep_map, _RET_IP_);
-+ else
-+ rwlock_release(&scst_suspend_dep_map, 1, _RET_IP_);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_clear:
-+ clear_bit(SCST_FLAG_SUSPENDING, &scst_flags);
-+ /* See comment about smp_mb() above */
-+ smp_mb__after_clear_bit();
-+ goto out_up;
-+}
-+EXPORT_SYMBOL_GPL(scst_suspend_activity);
-+
-+static void __scst_resume_activity(void)
-+{
-+ struct scst_cmd_threads *l;
-+
-+ TRACE_ENTRY();
-+
-+ suspend_count--;
-+ TRACE_MGMT_DBG("suspend_count %d left", suspend_count);
-+ if (suspend_count > 0)
-+ goto out;
-+
-+ clear_bit(SCST_FLAG_SUSPENDED, &scst_flags);
-+ /*
-+ * The barrier is needed to make sure all woken up threads see the
-+ * cleared flag. Not sure if it's really needed, but let's be safe.
-+ */
-+ smp_mb__after_clear_bit();
-+
-+ list_for_each_entry(l, &scst_cmd_threads_list, lists_list_entry) {
-+ wake_up_all(&l->cmd_list_waitQ);
-+ }
-+ wake_up_all(&scst_init_cmd_list_waitQ);
-+
-+ spin_lock_irq(&scst_mcmd_lock);
-+ if (!list_empty(&scst_delayed_mgmt_cmd_list)) {
-+ struct scst_mgmt_cmd *m;
-+ m = list_entry(scst_delayed_mgmt_cmd_list.next, typeof(*m),
-+ mgmt_cmd_list_entry);
-+ TRACE_MGMT_DBG("Moving delayed mgmt cmd %p to head of active "
-+ "mgmt cmd list", m);
-+ list_move(&m->mgmt_cmd_list_entry, &scst_active_mgmt_cmd_list);
-+ }
-+ spin_unlock_irq(&scst_mcmd_lock);
-+ wake_up_all(&scst_mgmt_cmd_list_waitQ);
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/**
-+ * scst_resume_activity() - globally resume all activities
-+ *
-+ * Resumes suspended by scst_suspend_activity() activities.
-+ */
-+void scst_resume_activity(void)
-+{
-+ TRACE_ENTRY();
-+
-+ rwlock_release(&scst_suspend_dep_map, 1, _RET_IP_);
-+
-+ mutex_lock(&scst_suspend_mutex);
-+ __scst_resume_activity();
-+ mutex_unlock(&scst_suspend_mutex);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(scst_resume_activity);
-+
-+static int scst_register_device(struct scsi_device *scsidp)
-+{
-+ int res;
-+ struct scst_device *dev, *d;
-+
-+ TRACE_ENTRY();
-+
-+ res = mutex_lock_interruptible(&scst_mutex);
-+ if (res != 0)
-+ goto out;
-+
-+ res = scst_alloc_device(GFP_KERNEL, &dev);
-+ if (res != 0)
-+ goto out_unlock;
-+
-+ dev->type = scsidp->type;
-+
-+ dev->virt_name = kasprintf(GFP_KERNEL, "%d:%d:%d:%d",
-+ scsidp->host->host_no,
-+ scsidp->channel, scsidp->id, scsidp->lun);
-+ if (dev->virt_name == NULL) {
-+ PRINT_ERROR("%s", "Unable to alloc device name");
-+ res = -ENOMEM;
-+ goto out_free_dev;
-+ }
-+
-+ list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
-+ if (strcmp(d->virt_name, dev->virt_name) == 0) {
-+ PRINT_ERROR("Device %s already exists", dev->virt_name);
-+ res = -EEXIST;
-+ goto out_free_dev;
-+ }
-+ }
-+
-+ dev->scsi_dev = scsidp;
-+
-+ list_add_tail(&dev->dev_list_entry, &scst_dev_list);
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ res = scst_dev_sysfs_create(dev);
-+ if (res != 0)
-+ goto out_del;
-+
-+ PRINT_INFO("Attached to scsi%d, channel %d, id %d, lun %d, "
-+ "type %d", scsidp->host->host_no, scsidp->channel,
-+ scsidp->id, scsidp->lun, scsidp->type);
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_del:
-+ list_del(&dev->dev_list_entry);
-+
-+out_free_dev:
-+ scst_free_device(dev);
-+
-+out_unlock:
-+ mutex_unlock(&scst_mutex);
-+ goto out;
-+}
-+
-+static void scst_unregister_device(struct scsi_device *scsidp)
-+{
-+ struct scst_device *d, *dev = NULL;
-+ struct scst_acg_dev *acg_dev, *aa;
-+
-+ TRACE_ENTRY();
-+
-+ scst_suspend_activity(false);
-+ mutex_lock(&scst_mutex);
-+
-+ list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
-+ if (d->scsi_dev == scsidp) {
-+ dev = d;
-+ TRACE_DBG("Device %p found", dev);
-+ break;
-+ }
-+ }
-+ if (dev == NULL) {
-+ PRINT_ERROR("SCST device for SCSI device %d:%d:%d:%d not found",
-+ scsidp->host->host_no, scsidp->channel, scsidp->id,
-+ scsidp->lun);
-+ goto out_unlock;
-+ }
-+
-+ dev->dev_unregistering = 1;
-+
-+ list_del(&dev->dev_list_entry);
-+
-+ scst_dg_dev_remove_by_dev(dev);
-+
-+ scst_assign_dev_handler(dev, &scst_null_devtype);
-+
-+ list_for_each_entry_safe(acg_dev, aa, &dev->dev_acg_dev_list,
-+ dev_acg_dev_list_entry) {
-+ scst_acg_del_lun(acg_dev->acg, acg_dev->lun, true);
-+ }
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ scst_resume_activity();
-+
-+ scst_dev_sysfs_del(dev);
-+
-+ PRINT_INFO("Detached from scsi%d, channel %d, id %d, lun %d, type %d",
-+ scsidp->host->host_no, scsidp->channel, scsidp->id,
-+ scsidp->lun, scsidp->type);
-+
-+ scst_free_device(dev);
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+
-+out_unlock:
-+ mutex_unlock(&scst_mutex);
-+ scst_resume_activity();
-+ goto out;
-+}
-+
-+static int scst_dev_handler_check(struct scst_dev_type *dev_handler)
-+{
-+ int res = 0;
-+
-+ if (dev_handler->parse == NULL) {
-+ PRINT_ERROR("scst dev handler %s must have "
-+ "parse() method.", dev_handler->name);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ if (((dev_handler->add_device != NULL) &&
-+ (dev_handler->del_device == NULL)) ||
-+ ((dev_handler->add_device == NULL) &&
-+ (dev_handler->del_device != NULL))) {
-+ PRINT_ERROR("Dev handler %s must either define both "
-+ "add_device() and del_device(), or none.",
-+ dev_handler->name);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ if (dev_handler->alloc_data_buf == NULL)
-+ dev_handler->alloc_data_buf_atomic = 1;
-+
-+ if (dev_handler->dev_done == NULL)
-+ dev_handler->dev_done_atomic = 1;
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static int scst_check_device_name(const char *dev_name)
-+{
-+ int res = 0;
-+
-+ if (strchr(dev_name, '/') != NULL) {
-+ PRINT_ERROR("Dev name %s contains illegal character '/'",
-+ dev_name);
-+ res = -EINVAL;
-+ }
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/**
-+ * scst_register_virtual_device() - register a virtual device.
-+ * @dev_handler: the device's device handler
-+ * @dev_name: the new device name, NULL-terminated string. Must be uniq
-+ * among all virtual devices in the system.
-+ *
-+ * Registers a virtual device and returns ID assigned to the device on
-+ * success, or negative value otherwise
-+ */
-+int scst_register_virtual_device(struct scst_dev_type *dev_handler,
-+ const char *dev_name)
-+{
-+ int res;
-+ struct scst_device *dev, *d;
-+ bool sysfs_del = false;
-+
-+ TRACE_ENTRY();
-+
-+ if (dev_handler == NULL) {
-+ PRINT_ERROR("%s: valid device handler must be supplied",
-+ __func__);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ if (dev_name == NULL) {
-+ PRINT_ERROR("%s: device name must be non-NULL", __func__);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ res = scst_check_device_name(dev_name);
-+ if (res != 0)
-+ goto out;
-+
-+ res = scst_dev_handler_check(dev_handler);
-+ if (res != 0)
-+ goto out;
-+
-+ res = scst_suspend_activity(true);
-+ if (res != 0)
-+ goto out;
-+
-+ res = mutex_lock_interruptible(&scst_mutex);
-+ if (res != 0)
-+ goto out_resume;
-+
-+ res = scst_alloc_device(GFP_KERNEL, &dev);
-+ if (res != 0)
-+ goto out_unlock;
-+
-+ dev->type = dev_handler->type;
-+ dev->scsi_dev = NULL;
-+ dev->virt_name = kstrdup(dev_name, GFP_KERNEL);
-+ if (dev->virt_name == NULL) {
-+ PRINT_ERROR("Unable to allocate virt_name for dev %s",
-+ dev_name);
-+ res = -ENOMEM;
-+ goto out_free_dev;
-+ }
-+
-+ while (1) {
-+ dev->virt_id = scst_virt_dev_last_id++;
-+ if (dev->virt_id > 0)
-+ break;
-+ scst_virt_dev_last_id = 1;
-+ }
-+
-+ res = dev->virt_id;
-+
-+ res = scst_pr_init_dev(dev);
-+ if (res != 0)
-+ goto out_free_dev;
-+
-+ /*
-+ * We can drop scst_mutex, because we have not yet added the dev in
-+ * scst_dev_list, so it "doesn't exist" yet.
-+ */
-+ mutex_unlock(&scst_mutex);
-+
-+ res = scst_dev_sysfs_create(dev);
-+ if (res != 0)
-+ goto out_lock_pr_clear_dev;
-+
-+ mutex_lock(&scst_mutex);
-+
-+ list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
-+ if (strcmp(d->virt_name, dev_name) == 0) {
-+ PRINT_ERROR("Device %s already exists", dev_name);
-+ res = -EEXIST;
-+ sysfs_del = true;
-+ goto out_pr_clear_dev;
-+ }
-+ }
-+
-+ res = scst_assign_dev_handler(dev, dev_handler);
-+ if (res != 0) {
-+ sysfs_del = true;
-+ goto out_pr_clear_dev;
-+ }
-+
-+ list_add_tail(&dev->dev_list_entry, &scst_dev_list);
-+
-+ mutex_unlock(&scst_mutex);
-+ scst_resume_activity();
-+
-+ res = dev->virt_id;
-+
-+ PRINT_INFO("Attached to virtual device %s (id %d)", dev_name, res);
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_lock_pr_clear_dev:
-+ mutex_lock(&scst_mutex);
-+
-+out_pr_clear_dev:
-+ scst_pr_clear_dev(dev);
-+
-+out_free_dev:
-+ mutex_unlock(&scst_mutex);
-+ if (sysfs_del)
-+ scst_dev_sysfs_del(dev);
-+ scst_free_device(dev);
-+ goto out_resume;
-+
-+out_unlock:
-+ mutex_unlock(&scst_mutex);
-+
-+out_resume:
-+ scst_resume_activity();
-+ goto out;
-+}
-+EXPORT_SYMBOL_GPL(scst_register_virtual_device);
-+
-+/**
-+ * scst_unregister_virtual_device() - unegister a virtual device.
-+ * @id: the device's ID, returned by the registration function
-+ */
-+void scst_unregister_virtual_device(int id)
-+{
-+ struct scst_device *d, *dev = NULL;
-+ struct scst_acg_dev *acg_dev, *aa;
-+
-+ TRACE_ENTRY();
-+
-+ scst_suspend_activity(false);
-+ mutex_lock(&scst_mutex);
-+
-+ list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
-+ if (d->virt_id == id) {
-+ dev = d;
-+ TRACE_DBG("Virtual device %p (id %d) found", dev, id);
-+ break;
-+ }
-+ }
-+ if (dev == NULL) {
-+ PRINT_ERROR("Virtual device (id %d) not found", id);
-+ goto out_unlock;
-+ }
-+
-+ dev->dev_unregistering = 1;
-+
-+ list_del(&dev->dev_list_entry);
-+
-+ scst_pr_clear_dev(dev);
-+
-+ scst_dg_dev_remove_by_dev(dev);
-+
-+ scst_assign_dev_handler(dev, &scst_null_devtype);
-+
-+ list_for_each_entry_safe(acg_dev, aa, &dev->dev_acg_dev_list,
-+ dev_acg_dev_list_entry) {
-+ scst_acg_del_lun(acg_dev->acg, acg_dev->lun, true);
-+ }
-+
-+ mutex_unlock(&scst_mutex);
-+ scst_resume_activity();
-+
-+ scst_dev_sysfs_del(dev);
-+
-+ PRINT_INFO("Detached from virtual device %s (id %d)",
-+ dev->virt_name, dev->virt_id);
-+
-+ scst_free_device(dev);
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+
-+out_unlock:
-+ mutex_unlock(&scst_mutex);
-+ scst_resume_activity();
-+ goto out;
-+}
-+EXPORT_SYMBOL_GPL(scst_unregister_virtual_device);
-+
-+/**
-+ * __scst_register_dev_driver() - register pass-through dev handler driver
-+ * @dev_type: dev handler template
-+ * @version: SCST_INTERFACE_VERSION version string to ensure that
-+ * SCST core and the dev handler use the same version of
-+ * the SCST interface
-+ *
-+ * Description:
-+ * Registers a pass-through dev handler driver. Returns 0 on success
-+ * or appropriate error code otherwise.
-+ */
-+int __scst_register_dev_driver(struct scst_dev_type *dev_type,
-+ const char *version)
-+{
-+ int res, exist;
-+ struct scst_dev_type *dt;
-+
-+ TRACE_ENTRY();
-+
-+ res = -EINVAL;
-+ if (strcmp(version, SCST_INTERFACE_VERSION) != 0) {
-+ PRINT_ERROR("Incorrect version of dev handler %s",
-+ dev_type->name);
-+ goto out;
-+ }
-+
-+ res = scst_dev_handler_check(dev_type);
-+ if (res != 0)
-+ goto out;
-+
-+ res = mutex_lock_interruptible(&scst_mutex);
-+ if (res != 0)
-+ goto out;
-+
-+ exist = 0;
-+ list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) {
-+ if (strcmp(dt->name, dev_type->name) == 0) {
-+ PRINT_ERROR("Device type handler \"%s\" already "
-+ "exists", dt->name);
-+ exist = 1;
-+ break;
-+ }
-+ }
-+ if (exist)
-+ goto out_unlock;
-+
-+ list_add_tail(&dev_type->dev_type_list_entry, &scst_dev_type_list);
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ res = scst_devt_sysfs_create(dev_type);
-+ if (res < 0)
-+ goto out;
-+
-+ PRINT_INFO("Device handler \"%s\" for type %d registered "
-+ "successfully", dev_type->name, dev_type->type);
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_unlock:
-+ mutex_unlock(&scst_mutex);
-+ goto out;
-+}
-+EXPORT_SYMBOL_GPL(__scst_register_dev_driver);
-+
-+/**
-+ * scst_unregister_dev_driver() - unregister pass-through dev handler driver
-+ */
-+void scst_unregister_dev_driver(struct scst_dev_type *dev_type)
-+{
-+ struct scst_device *dev;
-+ struct scst_dev_type *dt;
-+ int found = 0;
-+
-+ TRACE_ENTRY();
-+
-+ scst_suspend_activity(false);
-+ mutex_lock(&scst_mutex);
-+
-+ list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) {
-+ if (strcmp(dt->name, dev_type->name) == 0) {
-+ found = 1;
-+ break;
-+ }
-+ }
-+ if (!found) {
-+ PRINT_ERROR("Dev handler \"%s\" isn't registered",
-+ dev_type->name);
-+ goto out_up;
-+ }
-+
-+ list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
-+ if (dev->handler == dev_type) {
-+ scst_assign_dev_handler(dev, &scst_null_devtype);
-+ TRACE_DBG("Dev handler removed from device %p", dev);
-+ }
-+ }
-+
-+ list_del(&dev_type->dev_type_list_entry);
-+
-+ mutex_unlock(&scst_mutex);
-+ scst_resume_activity();
-+
-+ scst_devt_sysfs_del(dev_type);
-+
-+ PRINT_INFO("Device handler \"%s\" for type %d unloaded",
-+ dev_type->name, dev_type->type);
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+
-+out_up:
-+ mutex_unlock(&scst_mutex);
-+ scst_resume_activity();
-+ goto out;
-+}
-+EXPORT_SYMBOL_GPL(scst_unregister_dev_driver);
-+
-+/**
-+ * __scst_register_virtual_dev_driver() - register virtual dev handler driver
-+ * @dev_type: dev handler template
-+ * @version: SCST_INTERFACE_VERSION version string to ensure that
-+ * SCST core and the dev handler use the same version of
-+ * the SCST interface
-+ *
-+ * Description:
-+ * Registers a virtual dev handler driver. Returns 0 on success or
-+ * appropriate error code otherwise.
-+ */
-+int __scst_register_virtual_dev_driver(struct scst_dev_type *dev_type,
-+ const char *version)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ if (strcmp(version, SCST_INTERFACE_VERSION) != 0) {
-+ PRINT_ERROR("Incorrect version of virtual dev handler %s",
-+ dev_type->name);
-+ res = -EINVAL;
-+ goto out;
-+ }
-+
-+ res = scst_dev_handler_check(dev_type);
-+ if (res != 0)
-+ goto out;
-+
-+ res = mutex_lock_interruptible(&scst_mutex);
-+ if (res != 0)
-+ goto out;
-+ list_add_tail(&dev_type->dev_type_list_entry, &scst_virtual_dev_type_list);
-+ mutex_unlock(&scst_mutex);
-+
-+ res = scst_devt_sysfs_create(dev_type);
-+ if (res < 0)
-+ goto out;
-+
-+ if (dev_type->type != -1) {
-+ PRINT_INFO("Virtual device handler %s for type %d "
-+ "registered successfully", dev_type->name,
-+ dev_type->type);
-+ } else {
-+ PRINT_INFO("Virtual device handler \"%s\" registered "
-+ "successfully", dev_type->name);
-+ }
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+EXPORT_SYMBOL_GPL(__scst_register_virtual_dev_driver);
-+
-+/**
-+ * scst_unregister_virtual_dev_driver() - unregister virtual dev driver
-+ */
-+void scst_unregister_virtual_dev_driver(struct scst_dev_type *dev_type)
-+{
-+ TRACE_ENTRY();
-+
-+ mutex_lock(&scst_mutex);
-+
-+ /* Disable sysfs mgmt calls (e.g. addition of new devices) */
-+ list_del(&dev_type->dev_type_list_entry);
-+
-+ /* Wait for outstanding sysfs mgmt calls completed */
-+ while (dev_type->devt_active_sysfs_works_count > 0) {
-+ mutex_unlock(&scst_mutex);
-+ msleep(100);
-+ mutex_lock(&scst_mutex);
-+ }
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ scst_devt_sysfs_del(dev_type);
-+
-+ PRINT_INFO("Device handler \"%s\" unloaded", dev_type->name);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(scst_unregister_virtual_dev_driver);
-+
-+/* scst_mutex supposed to be held */
-+int scst_add_threads(struct scst_cmd_threads *cmd_threads,
-+ struct scst_device *dev, struct scst_tgt_dev *tgt_dev, int num)
-+{
-+ int res = 0, i;
-+ struct scst_cmd_thread_t *thr;
-+ int n = 0, tgt_dev_num = 0;
-+
-+ TRACE_ENTRY();
-+
-+ if (num == 0) {
-+ res = 0;
-+ goto out;
-+ }
-+
-+ list_for_each_entry(thr, &cmd_threads->threads_list, thread_list_entry) {
-+ n++;
-+ }
-+
-+ TRACE_DBG("cmd_threads %p, dev %s, tgt_dev %p, num %d, n %d",
-+ cmd_threads, dev ? dev->virt_name : NULL, tgt_dev, num, n);
-+
-+ if (tgt_dev != NULL) {
-+ struct scst_tgt_dev *t;
-+ list_for_each_entry(t, &tgt_dev->dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ if (t == tgt_dev)
-+ break;
-+ tgt_dev_num++;
-+ }
-+ }
-+
-+ for (i = 0; i < num; i++) {
-+ thr = kmalloc(sizeof(*thr), GFP_KERNEL);
-+ if (!thr) {
-+ res = -ENOMEM;
-+ PRINT_ERROR("Fail to allocate thr %d", res);
-+ goto out_wait;
-+ }
-+
-+ if (dev != NULL) {
-+ thr->cmd_thread = kthread_create(scst_cmd_thread,
-+ cmd_threads, "%.13s%d", dev->virt_name, n++);
-+ } else if (tgt_dev != NULL) {
-+ thr->cmd_thread = kthread_create(scst_cmd_thread,
-+ cmd_threads, "%.10s%d_%d",
-+ tgt_dev->dev->virt_name, tgt_dev_num, n++);
-+ } else
-+ thr->cmd_thread = kthread_create(scst_cmd_thread,
-+ cmd_threads, "scstd%d", n++);
-+
-+ if (IS_ERR(thr->cmd_thread)) {
-+ res = PTR_ERR(thr->cmd_thread);
-+ PRINT_ERROR("kthread_create() failed: %d", res);
-+ kfree(thr);
-+ goto out_wait;
-+ }
-+
-+ if (tgt_dev != NULL) {
-+ int rc;
-+ /*
-+ * sess->acg can be NULL here, if called from
-+ * scst_check_reassign_sess()!
-+ */
-+ rc = set_cpus_allowed_ptr(thr->cmd_thread,
-+ &tgt_dev->acg_dev->acg->acg_cpu_mask);
-+ if (rc != 0)
-+ PRINT_ERROR("Setting CPU affinity failed: "
-+ "%d", rc);
-+ }
-+
-+ list_add(&thr->thread_list_entry, &cmd_threads->threads_list);
-+ cmd_threads->nr_threads++;
-+
-+ TRACE_DBG("Added thr %p to threads list (nr_threads %d, n %d)",
-+ thr, cmd_threads->nr_threads, n);
-+
-+ wake_up_process(thr->cmd_thread);
-+ }
-+
-+out_wait:
-+ if (i > 0 && cmd_threads != &scst_main_cmd_threads) {
-+ /*
-+ * Wait for io_context gets initialized to avoid possible races
-+ * for it from the sharing it tgt_devs.
-+ */
-+ while (!*(volatile bool*)&cmd_threads->io_context_ready) {
-+ TRACE_DBG("Waiting for io_context for cmd_threads %p "
-+ "initialized", cmd_threads);
-+ msleep(50);
-+ }
-+ smp_rmb();
-+ }
-+
-+ if (res != 0)
-+ scst_del_threads(cmd_threads, i);
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/* scst_mutex supposed to be held */
-+void scst_del_threads(struct scst_cmd_threads *cmd_threads, int num)
-+{
-+ struct scst_cmd_thread_t *ct, *tmp;
-+
-+ TRACE_ENTRY();
-+
-+ if (num == 0)
-+ goto out;
-+
-+ list_for_each_entry_safe_reverse(ct, tmp, &cmd_threads->threads_list,
-+ thread_list_entry) {
-+ int rc;
-+ struct scst_device *dev;
-+
-+ rc = kthread_stop(ct->cmd_thread);
-+ if (rc != 0 && rc != -EINTR)
-+ TRACE_MGMT_DBG("kthread_stop() failed: %d", rc);
-+
-+ list_del(&ct->thread_list_entry);
-+
-+ list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
-+ struct scst_tgt_dev *tgt_dev;
-+ list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ scst_del_thr_data(tgt_dev, ct->cmd_thread);
-+ }
-+ }
-+
-+ kfree(ct);
-+
-+ cmd_threads->nr_threads--;
-+
-+ --num;
-+ if (num == 0)
-+ break;
-+ }
-+
-+ EXTRACHECKS_BUG_ON((cmd_threads->nr_threads == 0) &&
-+ (cmd_threads->io_context != NULL));
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/* The activity supposed to be suspended and scst_mutex held */
-+void scst_stop_dev_threads(struct scst_device *dev)
-+{
-+ struct scst_tgt_dev *tgt_dev;
-+
-+ TRACE_ENTRY();
-+
-+ list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ scst_tgt_dev_stop_threads(tgt_dev);
-+ }
-+
-+ if ((dev->threads_num > 0) &&
-+ (dev->threads_pool_type == SCST_THREADS_POOL_SHARED))
-+ scst_del_threads(&dev->dev_cmd_threads, -1);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/* The activity supposed to be suspended and scst_mutex held */
-+int scst_create_dev_threads(struct scst_device *dev)
-+{
-+ int res = 0;
-+ struct scst_tgt_dev *tgt_dev;
-+
-+ TRACE_ENTRY();
-+
-+ list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ res = scst_tgt_dev_setup_threads(tgt_dev);
-+ if (res != 0)
-+ goto out_err;
-+ }
-+
-+ if ((dev->threads_num > 0) &&
-+ (dev->threads_pool_type == SCST_THREADS_POOL_SHARED)) {
-+ res = scst_add_threads(&dev->dev_cmd_threads, dev, NULL,
-+ dev->threads_num);
-+ if (res != 0)
-+ goto out_err;
-+ }
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_err:
-+ scst_stop_dev_threads(dev);
-+ goto out;
-+}
-+
-+/* The activity supposed to be suspended and scst_mutex held */
-+int scst_assign_dev_handler(struct scst_device *dev,
-+ struct scst_dev_type *handler)
-+{
-+ int res = 0;
-+ struct scst_tgt_dev *tgt_dev;
-+ LIST_HEAD(attached_tgt_devs);
-+
-+ TRACE_ENTRY();
-+
-+ BUG_ON(handler == NULL);
-+
-+ if (dev->handler == handler)
-+ goto out;
-+
-+ if (dev->handler == NULL)
-+ goto assign;
-+
-+ if (dev->handler->detach_tgt) {
-+ list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ TRACE_DBG("Calling dev handler's detach_tgt(%p)",
-+ tgt_dev);
-+ dev->handler->detach_tgt(tgt_dev);
-+ TRACE_DBG("%s", "Dev handler's detach_tgt() returned");
-+ }
-+ }
-+
-+ /*
-+ * devt_dev sysfs must be created AFTER attach() and deleted BEFORE
-+ * detach() to avoid calls from sysfs for not yet ready or already dead
-+ * objects.
-+ */
-+ scst_devt_dev_sysfs_del(dev);
-+
-+ if (dev->handler->detach) {
-+ TRACE_DBG("%s", "Calling dev handler's detach()");
-+ dev->handler->detach(dev);
-+ TRACE_DBG("%s", "Old handler's detach() returned");
-+ }
-+
-+ scst_stop_dev_threads(dev);
-+
-+assign:
-+ dev->handler = handler;
-+
-+ if (handler == NULL)
-+ goto out;
-+
-+ dev->threads_num = handler->threads_num;
-+ dev->threads_pool_type = handler->threads_pool_type;
-+
-+ if (handler->attach) {
-+ TRACE_DBG("Calling new dev handler's attach(%p)", dev);
-+ res = handler->attach(dev);
-+ TRACE_DBG("New dev handler's attach() returned %d", res);
-+ if (res != 0) {
-+ PRINT_ERROR("New device handler's %s attach() "
-+ "failed: %d", handler->name, res);
-+ goto out;
-+ }
-+ }
-+
-+ res = scst_devt_dev_sysfs_create(dev);
-+ if (res != 0)
-+ goto out_detach;
-+
-+ if (handler->attach_tgt) {
-+ list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ TRACE_DBG("Calling dev handler's attach_tgt(%p)",
-+ tgt_dev);
-+ res = handler->attach_tgt(tgt_dev);
-+ TRACE_DBG("%s", "Dev handler's attach_tgt() returned");
-+ if (res != 0) {
-+ PRINT_ERROR("Device handler's %s attach_tgt() "
-+ "failed: %d", handler->name, res);
-+ goto out_err_remove_sysfs;
-+ }
-+ list_add_tail(&tgt_dev->extra_tgt_dev_list_entry,
-+ &attached_tgt_devs);
-+ }
-+ }
-+
-+ res = scst_create_dev_threads(dev);
-+ if (res != 0)
-+ goto out_err_detach_tgt;
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_err_detach_tgt:
-+ if (handler && handler->detach_tgt) {
-+ list_for_each_entry(tgt_dev, &attached_tgt_devs,
-+ extra_tgt_dev_list_entry) {
-+ TRACE_DBG("Calling handler's detach_tgt(%p)",
-+ tgt_dev);
-+ handler->detach_tgt(tgt_dev);
-+ TRACE_DBG("%s", "Handler's detach_tgt() returned");
-+ }
-+ }
-+
-+out_err_remove_sysfs:
-+ scst_devt_dev_sysfs_del(dev);
-+
-+out_detach:
-+ if (handler && handler->detach) {
-+ TRACE_DBG("%s", "Calling handler's detach()");
-+ handler->detach(dev);
-+ TRACE_DBG("%s", "Handler's detach() returned");
-+ }
-+
-+ dev->handler = &scst_null_devtype;
-+ dev->threads_num = scst_null_devtype.threads_num;
-+ dev->threads_pool_type = scst_null_devtype.threads_pool_type;
-+ goto out;
-+}
-+
-+/**
-+ * scst_init_threads() - initialize SCST processing threads pool
-+ *
-+ * Initializes scst_cmd_threads structure
-+ */
-+void scst_init_threads(struct scst_cmd_threads *cmd_threads)
-+{
-+ TRACE_ENTRY();
-+
-+ spin_lock_init(&cmd_threads->cmd_list_lock);
-+ INIT_LIST_HEAD(&cmd_threads->active_cmd_list);
-+ init_waitqueue_head(&cmd_threads->cmd_list_waitQ);
-+ INIT_LIST_HEAD(&cmd_threads->threads_list);
-+ mutex_init(&cmd_threads->io_context_mutex);
-+
-+ mutex_lock(&scst_suspend_mutex);
-+ list_add_tail(&cmd_threads->lists_list_entry,
-+ &scst_cmd_threads_list);
-+ mutex_unlock(&scst_suspend_mutex);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(scst_init_threads);
-+
-+/**
-+ * scst_deinit_threads() - deinitialize SCST processing threads pool
-+ *
-+ * Deinitializes scst_cmd_threads structure
-+ */
-+void scst_deinit_threads(struct scst_cmd_threads *cmd_threads)
-+{
-+ TRACE_ENTRY();
-+
-+ mutex_lock(&scst_suspend_mutex);
-+ list_del(&cmd_threads->lists_list_entry);
-+ mutex_unlock(&scst_suspend_mutex);
-+
-+ BUG_ON(cmd_threads->io_context);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(scst_deinit_threads);
-+
-+static void scst_stop_global_threads(void)
-+{
-+ TRACE_ENTRY();
-+
-+ mutex_lock(&scst_mutex);
-+
-+ scst_del_threads(&scst_main_cmd_threads, -1);
-+
-+ if (scst_mgmt_cmd_thread)
-+ kthread_stop(scst_mgmt_cmd_thread);
-+ if (scst_mgmt_thread)
-+ kthread_stop(scst_mgmt_thread);
-+ if (scst_init_cmd_thread)
-+ kthread_stop(scst_init_cmd_thread);
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/* It does NOT stop ran threads on error! */
-+static int scst_start_global_threads(int num)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ mutex_lock(&scst_mutex);
-+
-+ res = scst_add_threads(&scst_main_cmd_threads, NULL, NULL, num);
-+ if (res < 0)
-+ goto out_unlock;
-+
-+ scst_init_cmd_thread = kthread_run(scst_init_thread,
-+ NULL, "scst_initd");
-+ if (IS_ERR(scst_init_cmd_thread)) {
-+ res = PTR_ERR(scst_init_cmd_thread);
-+ PRINT_ERROR("kthread_create() for init cmd failed: %d", res);
-+ scst_init_cmd_thread = NULL;
-+ goto out_unlock;
-+ }
-+
-+ scst_mgmt_cmd_thread = kthread_run(scst_tm_thread,
-+ NULL, "scsi_tm");
-+ if (IS_ERR(scst_mgmt_cmd_thread)) {
-+ res = PTR_ERR(scst_mgmt_cmd_thread);
-+ PRINT_ERROR("kthread_create() for TM failed: %d", res);
-+ scst_mgmt_cmd_thread = NULL;
-+ goto out_unlock;
-+ }
-+
-+ scst_mgmt_thread = kthread_run(scst_global_mgmt_thread,
-+ NULL, "scst_mgmtd");
-+ if (IS_ERR(scst_mgmt_thread)) {
-+ res = PTR_ERR(scst_mgmt_thread);
-+ PRINT_ERROR("kthread_create() for mgmt failed: %d", res);
-+ scst_mgmt_thread = NULL;
-+ goto out_unlock;
-+ }
-+
-+out_unlock:
-+ mutex_unlock(&scst_mutex);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/**
-+ * scst_get_setup_id() - return SCST setup ID
-+ *
-+ * Returns SCST setup ID. This ID can be used for multiple
-+ * setups with the same configuration.
-+ */
-+unsigned int scst_get_setup_id(void)
-+{
-+ return scst_setup_id;
-+}
-+EXPORT_SYMBOL_GPL(scst_get_setup_id);
-+
-+static int scst_add(struct device *cdev, struct class_interface *intf)
-+{
-+ struct scsi_device *scsidp;
-+ int res = 0;
-+
-+ TRACE_ENTRY();
-+
-+ scsidp = to_scsi_device(cdev->parent);
-+
-+ if ((scsidp->host->hostt->name == NULL) ||
-+ (strcmp(scsidp->host->hostt->name, SCST_LOCAL_NAME) != 0))
-+ res = scst_register_device(scsidp);
-+
-+ TRACE_EXIT();
-+ return res;
-+}
-+
-+static void scst_remove(struct device *cdev, struct class_interface *intf)
-+{
-+ struct scsi_device *scsidp;
-+
-+ TRACE_ENTRY();
-+
-+ scsidp = to_scsi_device(cdev->parent);
-+
-+ if ((scsidp->host->hostt->name == NULL) ||
-+ (strcmp(scsidp->host->hostt->name, SCST_LOCAL_NAME) != 0))
-+ scst_unregister_device(scsidp);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+static struct class_interface scst_interface = {
-+ .add_dev = scst_add,
-+ .remove_dev = scst_remove,
-+};
-+
-+static void __init scst_print_config(void)
-+{
-+ char buf[128];
-+ int i, j;
-+
-+ i = snprintf(buf, sizeof(buf), "Enabled features: ");
-+ j = i;
-+
-+#ifdef CONFIG_SCST_STRICT_SERIALIZING
-+ i += snprintf(&buf[i], sizeof(buf) - i, "STRICT_SERIALIZING");
-+#endif
-+
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ i += snprintf(&buf[i], sizeof(buf) - i, "%sEXTRACHECKS",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+#ifdef CONFIG_SCST_TRACING
-+ i += snprintf(&buf[i], sizeof(buf) - i, "%sTRACING",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+#ifdef CONFIG_SCST_DEBUG
-+ i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+#ifdef CONFIG_SCST_DEBUG_TM
-+ i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG_TM",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+#ifdef CONFIG_SCST_DEBUG_RETRY
-+ i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG_RETRY",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+#ifdef CONFIG_SCST_DEBUG_OOM
-+ i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG_OOM",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+#ifdef CONFIG_SCST_DEBUG_SN
-+ i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG_SN",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+#ifdef CONFIG_SCST_USE_EXPECTED_VALUES
-+ i += snprintf(&buf[i], sizeof(buf) - i, "%sUSE_EXPECTED_VALUES",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
-+ i += snprintf(&buf[i], sizeof(buf) - i,
-+ "%sTEST_IO_IN_SIRQ",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+#ifdef CONFIG_SCST_STRICT_SECURITY
-+ i += snprintf(&buf[i], sizeof(buf) - i, "%sSTRICT_SECURITY",
-+ (j == i) ? "" : ", ");
-+#endif
-+
-+ if (j != i)
-+ PRINT_INFO("%s", buf);
-+}
-+
-+static int __init init_scst(void)
-+{
-+ int res, i;
-+ int scst_num_cpus;
-+
-+ TRACE_ENTRY();
-+
-+ {
-+ struct scsi_sense_hdr *shdr;
-+ struct scst_order_data *o;
-+ struct scst_cmd *c;
-+ BUILD_BUG_ON(SCST_SENSE_BUFFERSIZE < sizeof(*shdr));
-+ BUILD_BUG_ON(sizeof(o->curr_sn) != sizeof(o->expected_sn));
-+ BUILD_BUG_ON(sizeof(c->sn) != sizeof(o->expected_sn));
-+ }
-+
-+ mutex_init(&scst_mutex);
-+ mutex_init(&scst_mutex2);
-+ INIT_LIST_HEAD(&scst_template_list);
-+ INIT_LIST_HEAD(&scst_dev_list);
-+ INIT_LIST_HEAD(&scst_dev_type_list);
-+ INIT_LIST_HEAD(&scst_virtual_dev_type_list);
-+ spin_lock_init(&scst_main_lock);
-+ spin_lock_init(&scst_init_lock);
-+ init_waitqueue_head(&scst_init_cmd_list_waitQ);
-+ INIT_LIST_HEAD(&scst_init_cmd_list);
-+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
-+ scst_trace_flag = SCST_DEFAULT_LOG_FLAGS;
-+#endif
-+ spin_lock_init(&scst_mcmd_lock);
-+ INIT_LIST_HEAD(&scst_active_mgmt_cmd_list);
-+ INIT_LIST_HEAD(&scst_delayed_mgmt_cmd_list);
-+ init_waitqueue_head(&scst_mgmt_cmd_list_waitQ);
-+ init_waitqueue_head(&scst_mgmt_waitQ);
-+ spin_lock_init(&scst_mgmt_lock);
-+ INIT_LIST_HEAD(&scst_sess_init_list);
-+ INIT_LIST_HEAD(&scst_sess_shut_list);
-+ init_waitqueue_head(&scst_dev_cmd_waitQ);
-+ mutex_init(&scst_suspend_mutex);
-+ INIT_LIST_HEAD(&scst_cmd_threads_list);
-+ cpus_setall(default_cpu_mask);
-+
-+ scst_init_threads(&scst_main_cmd_threads);
-+
-+ res = scst_lib_init();
-+ if (res != 0)
-+ goto out_deinit_threads;
-+
-+ scst_num_cpus = num_online_cpus();
-+
-+ /* ToDo: register_cpu_notifier() */
-+
-+ if (scst_threads == 0)
-+ scst_threads = scst_num_cpus;
-+
-+ if (scst_threads < 1) {
-+ PRINT_ERROR("%s", "scst_threads can not be less than 1");
-+ scst_threads = scst_num_cpus;
-+ }
-+
-+#define INIT_CACHEP(p, s, o) do { \
-+ p = KMEM_CACHE(s, SCST_SLAB_FLAGS); \
-+ TRACE_MEM("Slab create: %s at %p size %zd", #s, p, \
-+ sizeof(struct s)); \
-+ if (p == NULL) { \
-+ res = -ENOMEM; \
-+ goto o; \
-+ } \
-+ } while (0)
-+
-+ INIT_CACHEP(scst_mgmt_cachep, scst_mgmt_cmd, out_lib_exit);
-+ INIT_CACHEP(scst_mgmt_stub_cachep, scst_mgmt_cmd_stub,
-+ out_destroy_mgmt_cache);
-+ INIT_CACHEP(scst_ua_cachep, scst_tgt_dev_UA,
-+ out_destroy_mgmt_stub_cache);
-+ {
-+ struct scst_sense { uint8_t s[SCST_SENSE_BUFFERSIZE]; };
-+ INIT_CACHEP(scst_sense_cachep, scst_sense,
-+ out_destroy_ua_cache);
-+ }
-+ INIT_CACHEP(scst_aen_cachep, scst_aen, out_destroy_sense_cache);
-+ INIT_CACHEP(scst_cmd_cachep, scst_cmd, out_destroy_aen_cache);
-+ INIT_CACHEP(scst_sess_cachep, scst_session, out_destroy_cmd_cache);
-+ INIT_CACHEP(scst_tgtd_cachep, scst_tgt_dev, out_destroy_sess_cache);
-+ INIT_CACHEP(scst_acgd_cachep, scst_acg_dev, out_destroy_tgt_cache);
-+
-+ scst_mgmt_mempool = mempool_create(64, mempool_alloc_slab,
-+ mempool_free_slab, scst_mgmt_cachep);
-+ if (scst_mgmt_mempool == NULL) {
-+ res = -ENOMEM;
-+ goto out_destroy_acg_cache;
-+ }
-+
-+ /*
-+ * All mgmt stubs, UAs and sense buffers are bursty and loosing them
-+ * may have fatal consequences, so let's have big pools for them.
-+ */
-+
-+ scst_mgmt_stub_mempool = mempool_create(1024, mempool_alloc_slab,
-+ mempool_free_slab, scst_mgmt_stub_cachep);
-+ if (scst_mgmt_stub_mempool == NULL) {
-+ res = -ENOMEM;
-+ goto out_destroy_mgmt_mempool;
-+ }
-+
-+ scst_ua_mempool = mempool_create(512, mempool_alloc_slab,
-+ mempool_free_slab, scst_ua_cachep);
-+ if (scst_ua_mempool == NULL) {
-+ res = -ENOMEM;
-+ goto out_destroy_mgmt_stub_mempool;
-+ }
-+
-+ scst_sense_mempool = mempool_create(1024, mempool_alloc_slab,
-+ mempool_free_slab, scst_sense_cachep);
-+ if (scst_sense_mempool == NULL) {
-+ res = -ENOMEM;
-+ goto out_destroy_ua_mempool;
-+ }
-+
-+ scst_aen_mempool = mempool_create(100, mempool_alloc_slab,
-+ mempool_free_slab, scst_aen_cachep);
-+ if (scst_aen_mempool == NULL) {
-+ res = -ENOMEM;
-+ goto out_destroy_sense_mempool;
-+ }
-+
-+ res = scst_sysfs_init();
-+ if (res != 0)
-+ goto out_destroy_aen_mempool;
-+
-+ scst_tg_init();
-+
-+ if (scst_max_cmd_mem == 0) {
-+ struct sysinfo si;
-+ si_meminfo(&si);
-+#if BITS_PER_LONG == 32
-+ scst_max_cmd_mem = min(
-+ (((uint64_t)(si.totalram - si.totalhigh) << PAGE_SHIFT)
-+ >> 20) >> 2, (uint64_t)1 << 30);
-+#else
-+ scst_max_cmd_mem = (((si.totalram - si.totalhigh) << PAGE_SHIFT)
-+ >> 20) >> 2;
-+#endif
-+ }
-+
-+ if (scst_max_dev_cmd_mem != 0) {
-+ if (scst_max_dev_cmd_mem > scst_max_cmd_mem) {
-+ PRINT_ERROR("scst_max_dev_cmd_mem (%d) > "
-+ "scst_max_cmd_mem (%d)",
-+ scst_max_dev_cmd_mem,
-+ scst_max_cmd_mem);
-+ scst_max_dev_cmd_mem = scst_max_cmd_mem;
-+ }
-+ } else
-+ scst_max_dev_cmd_mem = scst_max_cmd_mem * 2 / 5;
-+
-+ res = scst_sgv_pools_init(
-+ ((uint64_t)scst_max_cmd_mem << 10) >> (PAGE_SHIFT - 10), 0);
-+ if (res != 0)
-+ goto out_sysfs_cleanup;
-+
-+ res = scsi_register_interface(&scst_interface);
-+ if (res != 0)
-+ goto out_destroy_sgv_pool;
-+
-+ for (i = 0; i < (int)ARRAY_SIZE(scst_percpu_infos); i++) {
-+ atomic_set(&scst_percpu_infos[i].cpu_cmd_count, 0);
-+ spin_lock_init(&scst_percpu_infos[i].tasklet_lock);
-+ INIT_LIST_HEAD(&scst_percpu_infos[i].tasklet_cmd_list);
-+ tasklet_init(&scst_percpu_infos[i].tasklet,
-+ (void *)scst_cmd_tasklet,
-+ (unsigned long)&scst_percpu_infos[i]);
-+ }
-+
-+ TRACE_DBG("%d CPUs found, starting %d threads", scst_num_cpus,
-+ scst_threads);
-+
-+ res = scst_start_global_threads(scst_threads);
-+ if (res < 0)
-+ goto out_thread_free;
-+
-+ PRINT_INFO("SCST version %s loaded successfully (max mem for "
-+ "commands %dMB, per device %dMB)", SCST_VERSION_STRING,
-+ scst_max_cmd_mem, scst_max_dev_cmd_mem);
-+
-+ scst_print_config();
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_thread_free:
-+ scst_stop_global_threads();
-+
-+ scsi_unregister_interface(&scst_interface);
-+
-+out_destroy_sgv_pool:
-+ scst_sgv_pools_deinit();
-+ scst_tg_cleanup();
-+
-+out_sysfs_cleanup:
-+ scst_sysfs_cleanup();
-+
-+out_destroy_aen_mempool:
-+ mempool_destroy(scst_aen_mempool);
-+
-+out_destroy_sense_mempool:
-+ mempool_destroy(scst_sense_mempool);
-+
-+out_destroy_ua_mempool:
-+ mempool_destroy(scst_ua_mempool);
-+
-+out_destroy_mgmt_stub_mempool:
-+ mempool_destroy(scst_mgmt_stub_mempool);
-+
-+out_destroy_mgmt_mempool:
-+ mempool_destroy(scst_mgmt_mempool);
-+
-+out_destroy_acg_cache:
-+ kmem_cache_destroy(scst_acgd_cachep);
-+
-+out_destroy_tgt_cache:
-+ kmem_cache_destroy(scst_tgtd_cachep);
-+
-+out_destroy_sess_cache:
-+ kmem_cache_destroy(scst_sess_cachep);
-+
-+out_destroy_cmd_cache:
-+ kmem_cache_destroy(scst_cmd_cachep);
-+
-+out_destroy_aen_cache:
-+ kmem_cache_destroy(scst_aen_cachep);
-+
-+out_destroy_sense_cache:
-+ kmem_cache_destroy(scst_sense_cachep);
-+
-+out_destroy_ua_cache:
-+ kmem_cache_destroy(scst_ua_cachep);
-+
-+out_destroy_mgmt_stub_cache:
-+ kmem_cache_destroy(scst_mgmt_stub_cachep);
-+
-+out_destroy_mgmt_cache:
-+ kmem_cache_destroy(scst_mgmt_cachep);
-+
-+out_lib_exit:
-+ scst_lib_exit();
-+
-+out_deinit_threads:
-+ scst_deinit_threads(&scst_main_cmd_threads);
-+ goto out;
-+}
-+
-+static void __exit exit_scst(void)
-+{
-+ TRACE_ENTRY();
-+
-+ /* ToDo: unregister_cpu_notifier() */
-+
-+ scst_stop_global_threads();
-+
-+ scst_deinit_threads(&scst_main_cmd_threads);
-+
-+ scsi_unregister_interface(&scst_interface);
-+
-+ scst_sgv_pools_deinit();
-+
-+ scst_tg_cleanup();
-+
-+ scst_sysfs_cleanup();
-+
-+#define DEINIT_CACHEP(p) do { \
-+ kmem_cache_destroy(p); \
-+ p = NULL; \
-+ } while (0)
-+
-+ mempool_destroy(scst_mgmt_mempool);
-+ mempool_destroy(scst_mgmt_stub_mempool);
-+ mempool_destroy(scst_ua_mempool);
-+ mempool_destroy(scst_sense_mempool);
-+ mempool_destroy(scst_aen_mempool);
-+
-+ DEINIT_CACHEP(scst_mgmt_cachep);
-+ DEINIT_CACHEP(scst_mgmt_stub_cachep);
-+ DEINIT_CACHEP(scst_ua_cachep);
-+ DEINIT_CACHEP(scst_sense_cachep);
-+ DEINIT_CACHEP(scst_aen_cachep);
-+ DEINIT_CACHEP(scst_cmd_cachep);
-+ DEINIT_CACHEP(scst_sess_cachep);
-+ DEINIT_CACHEP(scst_tgtd_cachep);
-+ DEINIT_CACHEP(scst_acgd_cachep);
-+
-+ scst_lib_exit();
-+
-+ PRINT_INFO("%s", "SCST unloaded");
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+module_init(init_scst);
-+module_exit(exit_scst);
-+
-+MODULE_AUTHOR("Vladislav Bolkhovitin");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("SCSI target core");
-+MODULE_VERSION(SCST_VERSION_STRING);
-diff -uprN orig/linux-3.2/drivers/scst/scst_module.c linux-3.2/drivers/scst/scst_module.c
---- orig/linux-3.2/drivers/scst/scst_module.c
-+++ linux-3.2/drivers/scst/scst_module.c
-@@ -0,0 +1,70 @@
-+/*
-+ * scst_module.c
-+ *
-+ * Copyright (C) 2004 - 2011 Vladislav Bolkhovitin <vst@vlnb.net>
-+ * Copyright (C) 2004 - 2005 Leonid Stoljar
-+ * Copyright (C) 2007 - 2010 ID7 Ltd.
-+ * Copyright (C) 2010 - 2011 SCST Ltd.
-+ *
-+ * Support for loading target modules. The usage is similar to scsi_module.c
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation, version 2
-+ * of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <scst.h>
-+
-+static int __init init_this_scst_driver(void)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ res = scst_register_target_template(&driver_target_template);
-+ TRACE_DBG("scst_register_target_template() returned %d", res);
-+ if (res < 0)
-+ goto out;
-+
-+#ifdef SCST_REGISTER_INITIATOR_DRIVER
-+ driver_template.module = THIS_MODULE;
-+ scsi_register_module(MODULE_SCSI_HA, &driver_template);
-+ TRACE_DBG("driver_template.present=%d",
-+ driver_template.present);
-+ if (driver_template.present == 0) {
-+ res = -ENODEV;
-+ MOD_DEC_USE_COUNT;
-+ goto out;
-+ }
-+#endif
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static void __exit exit_this_scst_driver(void)
-+{
-+ TRACE_ENTRY();
-+
-+#ifdef SCST_REGISTER_INITIATOR_DRIVER
-+ scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
-+#endif
-+
-+ scst_unregister_target_template(&driver_target_template);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+module_init(init_this_scst_driver);
-+module_exit(exit_this_scst_driver);
-diff -uprN orig/linux-3.2/drivers/scst/scst_priv.h linux-3.2/drivers/scst/scst_priv.h
---- orig/linux-3.2/drivers/scst/scst_priv.h
-+++ linux-3.2/drivers/scst/scst_priv.h
-@@ -0,0 +1,646 @@
-+/*
-+ * scst_priv.h
-+ *
-+ * Copyright (C) 2004 - 2011 Vladislav Bolkhovitin <vst@vlnb.net>
-+ * Copyright (C) 2004 - 2005 Leonid Stoljar
-+ * Copyright (C) 2007 - 2010 ID7 Ltd.
-+ * Copyright (C) 2010 - 2011 SCST Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation, version 2
-+ * of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef __SCST_PRIV_H
-+#define __SCST_PRIV_H
-+
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <linux/export.h>
-+#include <scsi/scsi.h>
-+#include <scsi/scsi_cmnd.h>
-+#include <scsi/scsi_driver.h>
-+#include <scsi/scsi_device.h>
-+#include <scsi/scsi_host.h>
-+
-+#define LOG_PREFIX "scst"
-+
-+#include <scst/scst_debug.h>
-+
-+#define TRACE_RTRY 0x80000000
-+#define TRACE_SCSI_SERIALIZING 0x40000000
-+/** top being the edge away from the interrupt */
-+#define TRACE_SND_TOP 0x20000000
-+#define TRACE_RCV_TOP 0x01000000
-+/** bottom being the edge toward the interrupt */
-+#define TRACE_SND_BOT 0x08000000
-+#define TRACE_RCV_BOT 0x04000000
-+
-+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
-+#define trace_flag scst_trace_flag
-+extern unsigned long scst_trace_flag;
-+#endif
-+
-+#ifdef CONFIG_SCST_DEBUG
-+
-+#define SCST_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_PID | \
-+ TRACE_LINE | TRACE_FUNCTION | TRACE_SPECIAL | TRACE_MGMT | \
-+ TRACE_MGMT_DEBUG | TRACE_RTRY)
-+
-+#define TRACE_RETRY(args...) TRACE_DBG_FLAG(TRACE_RTRY, args)
-+#define TRACE_SN(args...) TRACE_DBG_FLAG(TRACE_SCSI_SERIALIZING, args)
-+#define TRACE_SEND_TOP(args...) TRACE_DBG_FLAG(TRACE_SND_TOP, args)
-+#define TRACE_RECV_TOP(args...) TRACE_DBG_FLAG(TRACE_RCV_TOP, args)
-+#define TRACE_SEND_BOT(args...) TRACE_DBG_FLAG(TRACE_SND_BOT, args)
-+#define TRACE_RECV_BOT(args...) TRACE_DBG_FLAG(TRACE_RCV_BOT, args)
-+
-+#else /* CONFIG_SCST_DEBUG */
-+
-+# ifdef CONFIG_SCST_TRACING
-+#define SCST_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | \
-+ TRACE_SPECIAL)
-+# else
-+#define SCST_DEFAULT_LOG_FLAGS 0
-+# endif
-+
-+#define TRACE_RETRY(args...)
-+#define TRACE_SN(args...)
-+#define TRACE_SEND_TOP(args...)
-+#define TRACE_RECV_TOP(args...)
-+#define TRACE_SEND_BOT(args...)
-+#define TRACE_RECV_BOT(args...)
-+
-+#endif
-+
-+/**
-+ ** Bits for scst_flags
-+ **/
-+
-+/*
-+ * Set if new commands initialization is being suspended for a while.
-+ * Used to let TM commands execute while preparing the suspend, since
-+ * RESET or ABORT could be necessary to free SCSI commands.
-+ */
-+#define SCST_FLAG_SUSPENDING 0
-+
-+/* Set if new commands initialization is suspended for a while */
-+#define SCST_FLAG_SUSPENDED 1
-+
-+/**
-+ ** Return codes for cmd state process functions. Codes are the same as
-+ ** for SCST_EXEC_* to avoid translation to them and, hence, have better code.
-+ **/
-+#define SCST_CMD_STATE_RES_CONT_NEXT SCST_EXEC_COMPLETED
-+#define SCST_CMD_STATE_RES_CONT_SAME SCST_EXEC_NOT_COMPLETED
-+#define SCST_CMD_STATE_RES_NEED_THREAD (SCST_EXEC_NOT_COMPLETED+1)
-+
-+/**
-+ ** Maximum count of uncompleted commands that an initiator could
-+ ** queue on any device. Then it will start getting TASK QUEUE FULL status.
-+ **/
-+#define SCST_MAX_TGT_DEV_COMMANDS 48
-+
-+/**
-+ ** Maximum count of uncompleted commands that could be queued on any device.
-+ ** Then initiators sending commands to this device will start getting
-+ ** TASK QUEUE FULL status.
-+ **/
-+#define SCST_MAX_DEV_COMMANDS 256
-+
-+#define SCST_TGT_RETRY_TIMEOUT (3/2*HZ)
-+
-+/* Activities suspending timeout */
-+#define SCST_SUSPENDING_TIMEOUT (90 * HZ)
-+
-+extern struct mutex scst_mutex2;
-+
-+extern int scst_threads;
-+
-+extern unsigned int scst_max_dev_cmd_mem;
-+
-+extern mempool_t *scst_mgmt_mempool;
-+extern mempool_t *scst_mgmt_stub_mempool;
-+extern mempool_t *scst_ua_mempool;
-+extern mempool_t *scst_sense_mempool;
-+extern mempool_t *scst_aen_mempool;
-+
-+extern struct kmem_cache *scst_cmd_cachep;
-+extern struct kmem_cache *scst_sess_cachep;
-+extern struct kmem_cache *scst_tgtd_cachep;
-+extern struct kmem_cache *scst_acgd_cachep;
-+
-+extern spinlock_t scst_main_lock;
-+
-+extern unsigned long scst_flags;
-+extern struct list_head scst_template_list;
-+extern struct list_head scst_dev_list;
-+extern struct list_head scst_dev_type_list;
-+extern struct list_head scst_virtual_dev_type_list;
-+extern wait_queue_head_t scst_dev_cmd_waitQ;
-+
-+extern unsigned int scst_setup_id;
-+
-+#define SCST_DEF_MAX_TASKLET_CMD 10
-+extern int scst_max_tasklet_cmd;
-+
-+extern spinlock_t scst_init_lock;
-+extern struct list_head scst_init_cmd_list;
-+extern wait_queue_head_t scst_init_cmd_list_waitQ;
-+extern unsigned int scst_init_poll_cnt;
-+
-+extern struct scst_cmd_threads scst_main_cmd_threads;
-+
-+extern spinlock_t scst_mcmd_lock;
-+/* The following lists protected by scst_mcmd_lock */
-+extern struct list_head scst_active_mgmt_cmd_list;
-+extern struct list_head scst_delayed_mgmt_cmd_list;
-+extern wait_queue_head_t scst_mgmt_cmd_list_waitQ;
-+
-+struct scst_percpu_info {
-+ atomic_t cpu_cmd_count;
-+ spinlock_t tasklet_lock;
-+ struct list_head tasklet_cmd_list;
-+ struct tasklet_struct tasklet;
-+} ____cacheline_aligned_in_smp;
-+extern struct scst_percpu_info scst_percpu_infos[NR_CPUS];
-+
-+extern wait_queue_head_t scst_mgmt_waitQ;
-+extern spinlock_t scst_mgmt_lock;
-+extern struct list_head scst_sess_init_list;
-+extern struct list_head scst_sess_shut_list;
-+
-+extern cpumask_t default_cpu_mask;
-+
-+struct scst_cmd_thread_t {
-+ struct task_struct *cmd_thread;
-+ struct list_head thread_list_entry;
-+};
-+
-+static inline bool scst_set_io_context(struct scst_cmd *cmd,
-+ struct io_context **old)
-+{
-+ bool res;
-+
-+#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
-+ return false;
-+#endif
-+
-+ if (cmd->cmd_threads == &scst_main_cmd_threads) {
-+ EXTRACHECKS_BUG_ON(in_interrupt());
-+ /*
-+ * No need for any ref counting action, because io_context
-+ * supposed to be cleared in the end of the caller function.
-+ */
-+ current->io_context = cmd->tgt_dev->async_io_context;
-+ res = true;
-+ TRACE_DBG("io_context %p (tgt_dev %p)", current->io_context,
-+ cmd->tgt_dev);
-+ EXTRACHECKS_BUG_ON(current->io_context == NULL);
-+ } else
-+ res = false;
-+
-+ return res;
-+}
-+
-+static inline void scst_reset_io_context(struct scst_tgt_dev *tgt_dev,
-+ struct io_context *old)
-+{
-+ current->io_context = old;
-+ TRACE_DBG("io_context %p reset", current->io_context);
-+ return;
-+}
-+
-+/*
-+ * Converts string presentation of threads pool type to enum.
-+ * Returns SCST_THREADS_POOL_TYPE_INVALID if the string is invalid.
-+ */
-+extern enum scst_dev_type_threads_pool_type scst_parse_threads_pool_type(
-+ const char *p, int len);
-+
-+extern int scst_add_threads(struct scst_cmd_threads *cmd_threads,
-+ struct scst_device *dev, struct scst_tgt_dev *tgt_dev, int num);
-+extern void scst_del_threads(struct scst_cmd_threads *cmd_threads, int num);
-+
-+extern int scst_create_dev_threads(struct scst_device *dev);
-+extern void scst_stop_dev_threads(struct scst_device *dev);
-+
-+extern int scst_tgt_dev_setup_threads(struct scst_tgt_dev *tgt_dev);
-+extern void scst_tgt_dev_stop_threads(struct scst_tgt_dev *tgt_dev);
-+
-+extern bool scst_del_thr_data(struct scst_tgt_dev *tgt_dev,
-+ struct task_struct *tsk);
-+
-+extern struct scst_dev_type scst_null_devtype;
-+
-+extern struct scst_cmd *__scst_check_deferred_commands(
-+ struct scst_order_data *order_data);
-+
-+/* Used to save the function call on the fast path */
-+static inline struct scst_cmd *scst_check_deferred_commands(
-+ struct scst_order_data *order_data)
-+{
-+ if (order_data->def_cmd_count == 0)
-+ return NULL;
-+ else
-+ return __scst_check_deferred_commands(order_data);
-+}
-+
-+static inline void scst_make_deferred_commands_active(
-+ struct scst_order_data *order_data)
-+{
-+ struct scst_cmd *c;
-+
-+ c = __scst_check_deferred_commands(order_data);
-+ if (c != NULL) {
-+ TRACE_SN("Adding cmd %p to active cmd list", c);
-+ spin_lock_irq(&c->cmd_threads->cmd_list_lock);
-+ list_add_tail(&c->cmd_list_entry,
-+ &c->cmd_threads->active_cmd_list);
-+ wake_up(&c->cmd_threads->cmd_list_waitQ);
-+ spin_unlock_irq(&c->cmd_threads->cmd_list_lock);
-+ }
-+
-+ return;
-+}
-+
-+void scst_inc_expected_sn(struct scst_order_data *order_data, atomic_t *slot);
-+int scst_check_hq_cmd(struct scst_cmd *cmd);
-+
-+void scst_unblock_deferred(struct scst_order_data *order_data,
-+ struct scst_cmd *cmd_sn);
-+
-+void scst_on_hq_cmd_response(struct scst_cmd *cmd);
-+void scst_xmit_process_aborted_cmd(struct scst_cmd *cmd);
-+
-+int scst_pre_parse(struct scst_cmd *cmd);
-+
-+int scst_cmd_thread(void *arg);
-+void scst_cmd_tasklet(long p);
-+int scst_init_thread(void *arg);
-+int scst_tm_thread(void *arg);
-+int scst_global_mgmt_thread(void *arg);
-+
-+void scst_zero_write_rest(struct scst_cmd *cmd);
-+void scst_limit_sg_write_len(struct scst_cmd *cmd);
-+void scst_adjust_resp_data_len(struct scst_cmd *cmd);
-+
-+int scst_queue_retry_cmd(struct scst_cmd *cmd, int finished_cmds);
-+
-+int scst_alloc_tgt(struct scst_tgt_template *tgtt, struct scst_tgt **tgt);
-+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);
-+
-+struct scst_acg *scst_alloc_add_acg(struct scst_tgt *tgt,
-+ const char *acg_name, bool tgt_acg);
-+void scst_del_free_acg(struct scst_acg *acg);
-+
-+struct scst_acg *scst_tgt_find_acg(struct scst_tgt *tgt, const char *name);
-+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_lun(struct scst_acg *acg, struct kobject *parent,
-+ struct scst_device *dev, uint64_t lun, int read_only,
-+ bool gen_scst_report_luns_changed, struct scst_acg_dev **out_acg_dev);
-+int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun,
-+ bool gen_scst_report_luns_changed);
-+
-+int scst_acg_add_acn(struct scst_acg *acg, const char *name);
-+void scst_del_free_acn(struct scst_acn *acn, bool reassign);
-+struct scst_acn *scst_find_acn(struct scst_acg *acg, const char *name);
-+
-+/* The activity supposed to be suspended and scst_mutex held */
-+static inline bool scst_acg_sess_is_empty(struct scst_acg *acg)
-+{
-+ return list_empty(&acg->acg_sess_list);
-+}
-+
-+int scst_prepare_request_sense(struct scst_cmd *orig_cmd);
-+int scst_finish_internal_cmd(struct scst_cmd *cmd);
-+
-+void scst_store_sense(struct scst_cmd *cmd);
-+
-+int scst_assign_dev_handler(struct scst_device *dev,
-+ struct scst_dev_type *handler);
-+
-+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_free_session_callback(struct scst_session *sess);
-+
-+struct scst_cmd *scst_alloc_cmd(const uint8_t *cdb,
-+ unsigned int cdb_len, gfp_t gfp_mask);
-+void scst_free_cmd(struct scst_cmd *cmd);
-+static inline void scst_destroy_cmd(struct scst_cmd *cmd)
-+{
-+ kmem_cache_free(scst_cmd_cachep, cmd);
-+ return;
-+}
-+
-+void scst_check_retries(struct scst_tgt *tgt);
-+
-+int scst_alloc_space(struct scst_cmd *cmd);
-+
-+int scst_lib_init(void);
-+void scst_lib_exit(void);
-+
-+__be64 scst_pack_lun(const uint64_t lun, enum scst_lun_addr_method addr_method);
-+uint64_t scst_unpack_lun(const uint8_t *lun, int len);
-+
-+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);
-+
-+static inline void scst_devt_cleanup(struct scst_dev_type *devt) { }
-+
-+void scst_tg_init(void);
-+void scst_tg_cleanup(void);
-+int scst_dg_add(struct kobject *parent, const char *name);
-+int scst_dg_remove(const char *name);
-+struct scst_dev_group *scst_lookup_dg_by_kobj(struct kobject *kobj);
-+int scst_dg_dev_add(struct scst_dev_group *dg, const char *name);
-+int scst_dg_dev_remove_by_name(struct scst_dev_group *dg, const char *name);
-+int scst_dg_dev_remove_by_dev(struct scst_device *dev);
-+int scst_tg_add(struct scst_dev_group *dg, const char *name);
-+int scst_tg_remove_by_name(struct scst_dev_group *dg, const char *name);
-+int scst_tg_set_state(struct scst_target_group *tg, enum scst_tg_state state);
-+int scst_tg_tgt_add(struct scst_target_group *tg, const char *name);
-+int scst_tg_tgt_remove_by_name(struct scst_target_group *tg, const char *name);
-+void scst_tg_tgt_remove_by_tgt(struct scst_tgt *tgt);
-+int scst_dg_sysfs_add(struct kobject *parent, struct scst_dev_group *dg);
-+void scst_dg_sysfs_del(struct scst_dev_group *dg);
-+int scst_dg_dev_sysfs_add(struct scst_dev_group *dg, struct scst_dg_dev *dgdev);
-+void scst_dg_dev_sysfs_del(struct scst_dev_group *dg,
-+ struct scst_dg_dev *dgdev);
-+int scst_tg_sysfs_add(struct scst_dev_group *dg,
-+ struct scst_target_group *tg);
-+void scst_tg_sysfs_del(struct scst_target_group *tg);
-+int scst_tg_tgt_sysfs_add(struct scst_target_group *tg,
-+ struct scst_tg_tgt *tg_tgt);
-+void scst_tg_tgt_sysfs_del(struct scst_target_group *tg,
-+ struct scst_tg_tgt *tg_tgt);
-+
-+extern const struct sysfs_ops scst_sysfs_ops;
-+int scst_sysfs_init(void);
-+void scst_sysfs_cleanup(void);
-+int scst_tgtt_sysfs_create(struct scst_tgt_template *tgtt);
-+void scst_tgtt_sysfs_del(struct scst_tgt_template *tgtt);
-+int scst_tgt_sysfs_create(struct scst_tgt *tgt);
-+void scst_tgt_sysfs_prepare_put(struct scst_tgt *tgt);
-+void scst_tgt_sysfs_del(struct scst_tgt *tgt);
-+int scst_sess_sysfs_create(struct scst_session *sess);
-+void scst_sess_sysfs_del(struct scst_session *sess);
-+int scst_recreate_sess_luns_link(struct scst_session *sess);
-+int scst_add_sgv_kobj(struct kobject *parent, const char *name);
-+void scst_del_put_sgv_kobj(void);
-+int scst_devt_sysfs_create(struct scst_dev_type *devt);
-+void scst_devt_sysfs_del(struct scst_dev_type *devt);
-+int scst_dev_sysfs_create(struct scst_device *dev);
-+void scst_dev_sysfs_del(struct scst_device *dev);
-+int scst_tgt_dev_sysfs_create(struct scst_tgt_dev *tgt_dev);
-+void scst_tgt_dev_sysfs_del(struct scst_tgt_dev *tgt_dev);
-+int scst_devt_dev_sysfs_create(struct scst_device *dev);
-+void scst_devt_dev_sysfs_del(struct scst_device *dev);
-+int scst_acg_sysfs_create(struct scst_tgt *tgt,
-+ struct scst_acg *acg);
-+void scst_acg_sysfs_del(struct scst_acg *acg);
-+int scst_acg_dev_sysfs_create(struct scst_acg_dev *acg_dev,
-+ struct kobject *parent);
-+void scst_acg_dev_sysfs_del(struct scst_acg_dev *acg_dev);
-+int scst_acn_sysfs_create(struct scst_acn *acn);
-+void scst_acn_sysfs_del(struct scst_acn *acn);
-+
-+void __scst_dev_check_set_UA(struct scst_device *dev, struct scst_cmd *exclude,
-+ const uint8_t *sense, int sense_len);
-+void scst_tgt_dev_del_free_UA(struct scst_tgt_dev *tgt_dev,
-+ struct scst_tgt_dev_UA *ua);
-+static inline void scst_dev_check_set_UA(struct scst_device *dev,
-+ struct scst_cmd *exclude, const uint8_t *sense, int sense_len)
-+{
-+ spin_lock_bh(&dev->dev_lock);
-+ __scst_dev_check_set_UA(dev, exclude, sense, sense_len);
-+ spin_unlock_bh(&dev->dev_lock);
-+ return;
-+}
-+void scst_dev_check_set_local_UA(struct scst_device *dev,
-+ struct scst_cmd *exclude, const uint8_t *sense, int sense_len);
-+
-+#define SCST_SET_UA_FLAG_AT_HEAD 1
-+#define SCST_SET_UA_FLAG_GLOBAL 2
-+
-+void scst_check_set_UA(struct scst_tgt_dev *tgt_dev,
-+ const uint8_t *sense, int sense_len, int flags);
-+int scst_set_pending_UA(struct scst_cmd *cmd);
-+
-+void scst_report_luns_changed(struct scst_acg *acg);
-+
-+void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
-+ bool other_ini, bool call_dev_task_mgmt_fn);
-+void scst_process_reset(struct scst_device *dev,
-+ struct scst_session *originator, struct scst_cmd *exclude_cmd,
-+ struct scst_mgmt_cmd *mcmd, bool setUA);
-+
-+bool scst_is_ua_global(const uint8_t *sense, int len);
-+void scst_requeue_ua(struct scst_cmd *cmd);
-+
-+struct scst_aen *scst_alloc_aen(struct scst_session *sess,
-+ uint64_t unpacked_lun);
-+void scst_free_aen(struct scst_aen *aen);
-+
-+void scst_gen_aen_or_ua(struct scst_tgt_dev *tgt_dev,
-+ int key, int asc, int ascq);
-+
-+static inline bool scst_is_implicit_hq_cmd(struct scst_cmd *cmd)
-+{
-+ return (cmd->op_flags & SCST_IMPLICIT_HQ) != 0;
-+}
-+
-+static inline bool scst_is_serialized_cmd(struct scst_cmd *cmd)
-+{
-+ return (cmd->op_flags & SCST_SERIALIZED) != 0;
-+}
-+
-+static inline bool scst_is_strictly_serialized_cmd(struct scst_cmd *cmd)
-+{
-+ return (cmd->op_flags & SCST_STRICTLY_SERIALIZED) == SCST_STRICTLY_SERIALIZED;
-+}
-+
-+/*
-+ * Some notes on devices "blocking". Blocking means that no
-+ * commands will go from SCST to underlying SCSI device until it
-+ * is unblocked. But, except for strictly serialized commands,
-+ * we don't care about all commands that already on the device.
-+ */
-+
-+extern void scst_block_dev(struct scst_device *dev);
-+extern void scst_unblock_dev(struct scst_device *dev);
-+
-+bool __scst_check_blocked_dev(struct scst_cmd *cmd);
-+
-+/*
-+ * Increases global SCST ref counters which prevent from entering into suspended
-+ * activities stage, so protects from any global management operations.
-+ */
-+static inline atomic_t *scst_get(void)
-+{
-+ atomic_t *a;
-+ /*
-+ * We don't mind if we because of preemption inc counter from another
-+ * CPU as soon in the majority cases we will the correct one. So, let's
-+ * have preempt_disable/enable only in the debug build to avoid warning.
-+ */
-+#ifdef CONFIG_DEBUG_PREEMPT
-+ preempt_disable();
-+#endif
-+ a = &scst_percpu_infos[smp_processor_id()].cpu_cmd_count;
-+ atomic_inc(a);
-+#ifdef CONFIG_DEBUG_PREEMPT
-+ preempt_enable();
-+#endif
-+ TRACE_DBG("Incrementing cpu_cmd_count %p (new value %d)",
-+ a, atomic_read(a));
-+ /* See comment about smp_mb() in scst_suspend_activity() */
-+ smp_mb__after_atomic_inc();
-+
-+ return a;
-+}
-+
-+/*
-+ * Decreases global SCST ref counters which prevent from entering into suspended
-+ * activities stage, so protects from any global management operations. On
-+ * all them zero, if suspending activities is waiting, it will be proceed.
-+ */
-+static inline void scst_put(atomic_t *a)
-+{
-+ int f;
-+ f = atomic_dec_and_test(a);
-+ /* See comment about smp_mb() in scst_suspend_activity() */
-+ if (unlikely(test_bit(SCST_FLAG_SUSPENDED, &scst_flags)) && f) {
-+ TRACE_MGMT_DBG("%s", "Waking up scst_dev_cmd_waitQ");
-+ wake_up_all(&scst_dev_cmd_waitQ);
-+ }
-+ TRACE_DBG("Decrementing cpu_cmd_count %p (new value %d)",
-+ a, atomic_read(a));
-+}
-+
-+int scst_get_cmd_counter(void);
-+
-+void scst_sched_session_free(struct scst_session *sess);
-+
-+static inline void scst_sess_get(struct scst_session *sess)
-+{
-+ atomic_inc(&sess->refcnt);
-+ TRACE_DBG("Incrementing sess %p refcnt (new value %d)",
-+ sess, atomic_read(&sess->refcnt));
-+}
-+
-+static inline void scst_sess_put(struct scst_session *sess)
-+{
-+ TRACE_DBG("Decrementing sess %p refcnt (new value %d)",
-+ sess, atomic_read(&sess->refcnt)-1);
-+ if (atomic_dec_and_test(&sess->refcnt))
-+ scst_sched_session_free(sess);
-+}
-+
-+static inline void __scst_cmd_get(struct scst_cmd *cmd)
-+{
-+ atomic_inc(&cmd->cmd_ref);
-+ TRACE_DBG("Incrementing cmd %p ref (new value %d)",
-+ cmd, atomic_read(&cmd->cmd_ref));
-+}
-+
-+static inline void __scst_cmd_put(struct scst_cmd *cmd)
-+{
-+ TRACE_DBG("Decrementing cmd %p ref (new value %d)",
-+ cmd, atomic_read(&cmd->cmd_ref)-1);
-+ if (atomic_dec_and_test(&cmd->cmd_ref))
-+ scst_free_cmd(cmd);
-+}
-+
-+extern void scst_throttle_cmd(struct scst_cmd *cmd);
-+extern void scst_unthrottle_cmd(struct scst_cmd *cmd);
-+
-+#ifdef CONFIG_SCST_DEBUG_TM
-+extern void tm_dbg_check_released_cmds(void);
-+extern int tm_dbg_check_cmd(struct scst_cmd *cmd);
-+extern void tm_dbg_release_cmd(struct scst_cmd *cmd);
-+extern void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn,
-+ int force);
-+extern int tm_dbg_is_release(void);
-+#else
-+static inline void tm_dbg_check_released_cmds(void) {}
-+static inline int tm_dbg_check_cmd(struct scst_cmd *cmd)
-+{
-+ return 0;
-+}
-+static inline void tm_dbg_release_cmd(struct scst_cmd *cmd) {}
-+static inline void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn,
-+ int force) {}
-+static inline int tm_dbg_is_release(void)
-+{
-+ return 0;
-+}
-+#endif /* CONFIG_SCST_DEBUG_TM */
-+
-+#ifdef CONFIG_SCST_DEBUG_SN
-+void scst_check_debug_sn(struct scst_cmd *cmd);
-+#else
-+static inline void scst_check_debug_sn(struct scst_cmd *cmd) {}
-+#endif
-+
-+static inline int scst_sn_before(uint32_t seq1, uint32_t seq2)
-+{
-+ return (int32_t)(seq1-seq2) < 0;
-+}
-+
-+int gen_relative_target_port_id(uint16_t *id);
-+bool scst_is_relative_target_port_id_unique(uint16_t id,
-+ const struct scst_tgt *t);
-+
-+#ifdef CONFIG_SCST_MEASURE_LATENCY
-+
-+void scst_set_start_time(struct scst_cmd *cmd);
-+void scst_set_cur_start(struct scst_cmd *cmd);
-+void scst_set_parse_time(struct scst_cmd *cmd);
-+void scst_set_alloc_buf_time(struct scst_cmd *cmd);
-+void scst_set_restart_waiting_time(struct scst_cmd *cmd);
-+void scst_set_rdy_to_xfer_time(struct scst_cmd *cmd);
-+void scst_set_pre_exec_time(struct scst_cmd *cmd);
-+void scst_set_exec_time(struct scst_cmd *cmd);
-+void scst_set_dev_done_time(struct scst_cmd *cmd);
-+void scst_set_xmit_time(struct scst_cmd *cmd);
-+void scst_set_tgt_on_free_time(struct scst_cmd *cmd);
-+void scst_set_dev_on_free_time(struct scst_cmd *cmd);
-+void scst_update_lat_stats(struct scst_cmd *cmd);
-+
-+#else
-+
-+static inline void scst_set_start_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_cur_start(struct scst_cmd *cmd) {}
-+static inline void scst_set_parse_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_alloc_buf_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_restart_waiting_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_rdy_to_xfer_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_pre_exec_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_exec_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_dev_done_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_xmit_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_tgt_on_free_time(struct scst_cmd *cmd) {}
-+static inline void scst_set_dev_on_free_time(struct scst_cmd *cmd) {}
-+static inline void scst_update_lat_stats(struct scst_cmd *cmd) {}
-+
-+#endif /* CONFIG_SCST_MEASURE_LATENCY */
-+
-+#endif /* __SCST_PRIV_H */
-diff -uprN orig/linux-3.2/drivers/scst/scst_targ.c linux-3.2/drivers/scst/scst_targ.c
---- orig/linux-3.2/drivers/scst/scst_targ.c
-+++ linux-3.2/drivers/scst/scst_targ.c
-@@ -0,0 +1,6705 @@
-+/*
-+ * scst_targ.c
-+ *
-+ * Copyright (C) 2004 - 2011 Vladislav Bolkhovitin <vst@vlnb.net>
-+ * Copyright (C) 2004 - 2005 Leonid Stoljar
-+ * Copyright (C) 2007 - 2010 ID7 Ltd.
-+ * Copyright (C) 2010 - 2011 SCST Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation, version 2
-+ * of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/list.h>
-+#include <linux/spinlock.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/unistd.h>
-+#include <linux/string.h>
-+#include <linux/kthread.h>
-+#include <linux/delay.h>
-+#include <linux/ktime.h>
-+
-+#include <scst/scst.h>
-+#include "scst_priv.h"
-+#include "scst_pres.h"
-+
-+#if 0 /* Let's disable it for now to see if users will complain about it */
-+/* Deleting it don't forget to delete dev_cmd_count */
-+#define CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT
-+#endif
-+
-+static void scst_cmd_set_sn(struct scst_cmd *cmd);
-+static int __scst_init_cmd(struct scst_cmd *cmd);
-+static void scst_finish_cmd_mgmt(struct scst_cmd *cmd);
-+static struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess,
-+ uint64_t tag, bool to_abort);
-+static void scst_process_redirect_cmd(struct scst_cmd *cmd,
-+ enum scst_exec_context context, int check_retries);
-+
-+/**
-+ * scst_post_parse() - do post parse actions
-+ *
-+ * This function must be called by dev handler after its parse() callback
-+ * returned SCST_CMD_STATE_STOP before calling scst_process_active_cmd().
-+ */
-+void scst_post_parse(struct scst_cmd *cmd)
-+{
-+ scst_set_parse_time(cmd);
-+}
-+EXPORT_SYMBOL_GPL(scst_post_parse);
-+
-+/**
-+ * scst_post_alloc_data_buf() - do post alloc_data_buf actions
-+ *
-+ * This function must be called by dev handler after its alloc_data_buf()
-+ * callback returned SCST_CMD_STATE_STOP before calling
-+ * scst_process_active_cmd().
-+ */
-+void scst_post_alloc_data_buf(struct scst_cmd *cmd)
-+{
-+ scst_set_alloc_buf_time(cmd);
-+}
-+EXPORT_SYMBOL_GPL(scst_post_alloc_data_buf);
-+
-+static inline void scst_schedule_tasklet(struct scst_cmd *cmd)
-+{
-+ struct scst_percpu_info *i = &scst_percpu_infos[smp_processor_id()];
-+ unsigned long flags;
-+
-+ if (atomic_read(&i->cpu_cmd_count) <= scst_max_tasklet_cmd) {
-+ spin_lock_irqsave(&i->tasklet_lock, flags);
-+ TRACE_DBG("Adding cmd %p to tasklet %d cmd list", cmd,
-+ smp_processor_id());
-+ list_add_tail(&cmd->cmd_list_entry, &i->tasklet_cmd_list);
-+ spin_unlock_irqrestore(&i->tasklet_lock, flags);
-+
-+ tasklet_schedule(&i->tasklet);
-+ } else {
-+ spin_lock_irqsave(&cmd->cmd_threads->cmd_list_lock, flags);
-+ TRACE_DBG("Too many tasklet commands (%d), adding cmd %p to "
-+ "active cmd list", atomic_read(&i->cpu_cmd_count), cmd);
-+ list_add_tail(&cmd->cmd_list_entry,
-+ &cmd->cmd_threads->active_cmd_list);
-+ wake_up(&cmd->cmd_threads->cmd_list_waitQ);
-+ spin_unlock_irqrestore(&cmd->cmd_threads->cmd_list_lock, flags);
-+ }
-+ return;
-+}
-+
-+/* No locks */
-+static bool scst_check_blocked_dev(struct scst_cmd *cmd)
-+{
-+ bool res;
-+ struct scst_device *dev = cmd->dev;
-+
-+ spin_lock_bh(&dev->dev_lock);
-+
-+ dev->on_dev_cmd_count++;
-+ cmd->dec_on_dev_needed = 1;
-+ TRACE_DBG("New inc on_dev_count %d (cmd %p)", dev->on_dev_cmd_count,
-+ cmd);
-+
-+ scst_inc_pr_readers_count(cmd, true);
-+
-+ if (unlikely(dev->block_count > 0) ||
-+ unlikely(dev->dev_double_ua_possible) ||
-+ unlikely(scst_is_serialized_cmd(cmd)))
-+ res = __scst_check_blocked_dev(cmd);
-+ else
-+ res = false;
-+
-+ if (unlikely(res)) {
-+ /* Undo increments */
-+ dev->on_dev_cmd_count--;
-+ cmd->dec_on_dev_needed = 0;
-+ TRACE_DBG("New dec on_dev_count %d (cmd %p)",
-+ dev->on_dev_cmd_count, cmd);
-+
-+ scst_dec_pr_readers_count(cmd, true);
-+ }
-+
-+ spin_unlock_bh(&dev->dev_lock);
-+
-+ return res;
-+}
-+
-+/* No locks */
-+static void scst_check_unblock_dev(struct scst_cmd *cmd)
-+{
-+ struct scst_device *dev = cmd->dev;
-+
-+ spin_lock_bh(&dev->dev_lock);
-+
-+ if (likely(cmd->dec_on_dev_needed)) {
-+ dev->on_dev_cmd_count--;
-+ cmd->dec_on_dev_needed = 0;
-+ TRACE_DBG("New dec on_dev_count %d (cmd %p)",
-+ dev->on_dev_cmd_count, cmd);
-+ }
-+
-+ if (unlikely(cmd->dec_pr_readers_count_needed))
-+ scst_dec_pr_readers_count(cmd, true);
-+
-+ if (unlikely(cmd->unblock_dev)) {
-+ TRACE_MGMT_DBG("cmd %p (tag %llu): unblocking dev %s", cmd,
-+ (long long unsigned int)cmd->tag, dev->virt_name);
-+ cmd->unblock_dev = 0;
-+ scst_unblock_dev(dev);
-+ } else if (unlikely(dev->strictly_serialized_cmd_waiting)) {
-+ if (dev->on_dev_cmd_count == 0) {
-+ TRACE_MGMT_DBG("Strictly serialized cmd waiting: "
-+ "unblocking dev %s", dev->virt_name);
-+ scst_unblock_dev(dev);
-+ }
-+ }
-+
-+ spin_unlock_bh(&dev->dev_lock);
-+ return;
-+}
-+
-+/**
-+ * scst_rx_cmd() - create new command
-+ * @sess: SCST session
-+ * @lun: LUN for the command
-+ * @lun_len: length of the LUN in bytes
-+ * @cdb: CDB of the command
-+ * @cdb_len: length of the CDB in bytes
-+ * @atomic: true, if current context is atomic
-+ *
-+ * Description:
-+ * Creates new SCST command. Returns new command on success or
-+ * NULL otherwise.
-+ *
-+ * Must not be called in parallel with scst_unregister_session() for the
-+ * same session.
-+ */
-+struct scst_cmd *scst_rx_cmd(struct scst_session *sess,
-+ const uint8_t *lun, int lun_len, const uint8_t *cdb,
-+ unsigned int cdb_len, int atomic)
-+{
-+ struct scst_cmd *cmd;
-+
-+ TRACE_ENTRY();
-+
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ if (unlikely(sess->shut_phase != SCST_SESS_SPH_READY)) {
-+ PRINT_CRIT_ERROR("%s",
-+ "New cmd while shutting down the session");
-+ BUG();
-+ }
-+#endif
-+
-+ cmd = scst_alloc_cmd(cdb, cdb_len, atomic ? GFP_ATOMIC : GFP_KERNEL);
-+ if (unlikely(cmd == NULL))
-+ goto out;
-+
-+ cmd->sess = sess;
-+ cmd->tgt = sess->tgt;
-+ cmd->tgtt = sess->tgt->tgtt;
-+
-+ cmd->lun = scst_unpack_lun(lun, lun_len);
-+ if (unlikely(cmd->lun == NO_SUCH_LUN))
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_lun_not_supported));
-+
-+ TRACE_DBG("cmd %p, sess %p", cmd, sess);
-+ scst_sess_get(sess);
-+
-+out:
-+ TRACE_EXIT();
-+ return cmd;
-+}
-+EXPORT_SYMBOL(scst_rx_cmd);
-+
-+/*
-+ * No locks, but might be on IRQ. Returns 0 on success, <0 if processing of
-+ * this command should be stopped.
-+ */
-+static int scst_init_cmd(struct scst_cmd *cmd, enum scst_exec_context *context)
-+{
-+ int rc, res = 0;
-+
-+ TRACE_ENTRY();
-+
-+ /* See the comment in scst_do_job_init() */
-+ if (unlikely(!list_empty(&scst_init_cmd_list))) {
-+ TRACE_MGMT_DBG("%s", "init cmd list busy");
-+ goto out_redirect;
-+ }
-+ /*
-+ * Memory barrier isn't necessary here, because CPU appears to
-+ * be self-consistent and we don't care about the race, described
-+ * in comment in scst_do_job_init().
-+ */
-+
-+ rc = __scst_init_cmd(cmd);
-+ if (unlikely(rc > 0))
-+ goto out_redirect;
-+ else if (unlikely(rc != 0)) {
-+ res = 1;
-+ goto out;
-+ }
-+
-+ EXTRACHECKS_BUG_ON(*context == SCST_CONTEXT_SAME);
-+
-+#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
-+ if (cmd->op_flags & SCST_TEST_IO_IN_SIRQ_ALLOWED)
-+ goto out;
-+#endif
-+
-+ /* Small context optimization */
-+ if ((*context == SCST_CONTEXT_TASKLET) ||
-+ (*context == SCST_CONTEXT_DIRECT_ATOMIC)) {
-+ /*
-+ * If any data_direction not set, it's SCST_DATA_UNKNOWN,
-+ * which is 0, so we can safely | them
-+ */
-+ BUILD_BUG_ON(SCST_DATA_UNKNOWN != 0);
-+ if ((cmd->data_direction | cmd->expected_data_direction) & SCST_DATA_WRITE) {
-+ if (!test_bit(SCST_TGT_DEV_AFTER_INIT_WR_ATOMIC,
-+ &cmd->tgt_dev->tgt_dev_flags))
-+ *context = SCST_CONTEXT_THREAD;
-+ } else
-+ *context = SCST_CONTEXT_THREAD;
-+ }
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_redirect:
-+ if (cmd->preprocessing_only) {
-+ /*
-+ * Poor man solution for single threaded targets, where
-+ * blocking receiver at least sometimes means blocking all.
-+ * For instance, iSCSI target won't be able to receive
-+ * Data-Out PDUs.
-+ */
-+ BUG_ON(*context != SCST_CONTEXT_DIRECT);
-+ scst_set_busy(cmd);
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ res = 1;
-+ /* Keep initiator away from too many BUSY commands */
-+ msleep(50);
-+ } else {
-+ unsigned long flags;
-+ spin_lock_irqsave(&scst_init_lock, flags);
-+ TRACE_MGMT_DBG("Adding cmd %p to init cmd list)", cmd);
-+ list_add_tail(&cmd->cmd_list_entry, &scst_init_cmd_list);
-+ if (test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))
-+ scst_init_poll_cnt++;
-+ spin_unlock_irqrestore(&scst_init_lock, flags);
-+ wake_up(&scst_init_cmd_list_waitQ);
-+ res = -1;
-+ }
-+ goto out;
-+}
-+
-+/**
-+ * scst_cmd_init_done() - the command's initialization done
-+ * @cmd: SCST command
-+ * @pref_context: preferred command execution context
-+ *
-+ * Description:
-+ * Notifies SCST that the driver finished its part of the command
-+ * initialization, and the command is ready for execution.
-+ * The second argument sets preferred command execution context.
-+ * See SCST_CONTEXT_* constants for details.
-+ *
-+ * !!IMPORTANT!!
-+ *
-+ * If cmd->set_sn_on_restart_cmd not set, this function, as well as
-+ * scst_cmd_init_stage1_done() and scst_restart_cmd(), must not be
-+ * called simultaneously for the same session (more precisely,
-+ * for the same session/LUN, i.e. tgt_dev), i.e. they must be
-+ * somehow externally serialized. This is needed to have lock free fast
-+ * path in scst_cmd_set_sn(). For majority of targets those functions are
-+ * naturally serialized by the single source of commands. Only iSCSI
-+ * immediate commands with multiple connections per session seems to be an
-+ * exception. For it, some mutex/lock shall be used for the serialization.
-+ */
-+void scst_cmd_init_done(struct scst_cmd *cmd,
-+ enum scst_exec_context pref_context)
-+{
-+ unsigned long flags;
-+ struct scst_session *sess = cmd->sess;
-+ int rc;
-+
-+ TRACE_ENTRY();
-+
-+ scst_set_start_time(cmd);
-+
-+ TRACE_DBG("Preferred context: %d (cmd %p)", pref_context, cmd);
-+ TRACE(TRACE_SCSI, "tag=%llu, lun=%lld, CDB len=%d, queue_type=%x "
-+ "(cmd %p, sess %p)", (long long unsigned int)cmd->tag,
-+ (long long unsigned int)cmd->lun, cmd->cdb_len,
-+ cmd->queue_type, cmd, sess);
-+ PRINT_BUFF_FLAG(TRACE_SCSI|TRACE_RCV_BOT, "Receiving CDB",
-+ cmd->cdb, cmd->cdb_len);
-+
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ if (unlikely((in_irq() || irqs_disabled())) &&
-+ ((pref_context == SCST_CONTEXT_DIRECT) ||
-+ (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) {
-+ PRINT_ERROR("Wrong context %d in IRQ from target %s, use "
-+ "SCST_CONTEXT_THREAD instead", pref_context,
-+ cmd->tgtt->name);
-+ dump_stack();
-+ pref_context = SCST_CONTEXT_THREAD;
-+ }
-+#endif
-+
-+ atomic_inc(&sess->sess_cmd_count);
-+
-+ spin_lock_irqsave(&sess->sess_list_lock, flags);
-+
-+ if (unlikely(sess->init_phase != SCST_SESS_IPH_READY)) {
-+ /*
-+ * We must always keep commands in the sess list from the
-+ * very beginning, because otherwise they can be missed during
-+ * TM processing. This check is needed because there might be
-+ * old, i.e. deferred, commands and new, i.e. just coming, ones.
-+ */
-+ if (cmd->sess_cmd_list_entry.next == NULL)
-+ list_add_tail(&cmd->sess_cmd_list_entry,
-+ &sess->sess_cmd_list);
-+ switch (sess->init_phase) {
-+ case SCST_SESS_IPH_SUCCESS:
-+ break;
-+ case SCST_SESS_IPH_INITING:
-+ TRACE_DBG("Adding cmd %p to init deferred cmd list",
-+ cmd);
-+ list_add_tail(&cmd->cmd_list_entry,
-+ &sess->init_deferred_cmd_list);
-+ spin_unlock_irqrestore(&sess->sess_list_lock, flags);
-+ goto out;
-+ case SCST_SESS_IPH_FAILED:
-+ spin_unlock_irqrestore(&sess->sess_list_lock, flags);
-+ scst_set_busy(cmd);
-+ goto set_state;
-+ default:
-+ BUG();
-+ }
-+ } else
-+ list_add_tail(&cmd->sess_cmd_list_entry,
-+ &sess->sess_cmd_list);
-+
-+ spin_unlock_irqrestore(&sess->sess_list_lock, flags);
-+
-+ if (unlikely(cmd->queue_type >= SCST_CMD_QUEUE_ACA)) {
-+ PRINT_ERROR("Unsupported queue type %d", cmd->queue_type);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_message));
-+ }
-+
-+set_state:
-+ if (unlikely(cmd->status != SAM_STAT_GOOD)) {
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ goto active;
-+ }
-+
-+ /*
-+ * Cmd must be inited here to preserve the order. In case if cmd
-+ * already preliminary completed by target driver we need to init
-+ * cmd anyway to find out in which format we should return sense.
-+ */
-+ cmd->state = SCST_CMD_STATE_INIT;
-+ rc = scst_init_cmd(cmd, &pref_context);
-+ if (unlikely(rc < 0))
-+ goto out;
-+
-+active:
-+ /* Here cmd must not be in any cmd list, no locks */
-+ switch (pref_context) {
-+ case SCST_CONTEXT_TASKLET:
-+ scst_schedule_tasklet(cmd);
-+ break;
-+
-+ default:
-+ PRINT_ERROR("Context %x is undefined, using the thread one",
-+ pref_context);
-+ /* go through */
-+ case SCST_CONTEXT_THREAD:
-+ spin_lock_irqsave(&cmd->cmd_threads->cmd_list_lock, flags);
-+ TRACE_DBG("Adding cmd %p to active cmd list", cmd);
-+ if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
-+ list_add(&cmd->cmd_list_entry,
-+ &cmd->cmd_threads->active_cmd_list);
-+ else
-+ list_add_tail(&cmd->cmd_list_entry,
-+ &cmd->cmd_threads->active_cmd_list);
-+ wake_up(&cmd->cmd_threads->cmd_list_waitQ);
-+ spin_unlock_irqrestore(&cmd->cmd_threads->cmd_list_lock, flags);
-+ break;
-+
-+ case SCST_CONTEXT_DIRECT:
-+ scst_process_active_cmd(cmd, false);
-+ break;
-+
-+ case SCST_CONTEXT_DIRECT_ATOMIC:
-+ scst_process_active_cmd(cmd, true);
-+ break;
-+ }
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL(scst_cmd_init_done);
-+
-+int scst_pre_parse(struct scst_cmd *cmd)
-+{
-+ int res;
-+ struct scst_device *dev = cmd->dev;
-+ int rc;
-+
-+ TRACE_ENTRY();
-+
-+ /*
-+ * Expected transfer data supplied by the SCSI transport via the
-+ * target driver are untrusted, so we prefer to fetch them from CDB.
-+ * Additionally, not all transports support supplying the expected
-+ * transfer data.
-+ */
-+
-+ rc = scst_get_cdb_info(cmd);
-+ if (unlikely(rc != 0)) {
-+ if (rc > 0) {
-+ PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len);
-+ goto out_err;
-+ }
-+
-+ EXTRACHECKS_BUG_ON(cmd->op_flags & SCST_INFO_VALID);
-+
-+ TRACE(TRACE_MINOR, "Unknown opcode 0x%02x for %s. "
-+ "Should you update scst_scsi_op_table?",
-+ cmd->cdb[0], dev->handler->name);
-+ PRINT_BUFF_FLAG(TRACE_MINOR, "Failed CDB", cmd->cdb,
-+ cmd->cdb_len);
-+ } else
-+ EXTRACHECKS_BUG_ON(!(cmd->op_flags & SCST_INFO_VALID));
-+
-+#ifdef CONFIG_SCST_STRICT_SERIALIZING
-+ cmd->inc_expected_sn_on_done = 1;
-+#else
-+ cmd->inc_expected_sn_on_done = dev->handler->exec_sync ||
-+ (!dev->has_own_order_mgmt &&
-+ (dev->queue_alg == SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER ||
-+ cmd->queue_type == SCST_CMD_QUEUE_ORDERED));
-+#endif
-+
-+ TRACE_DBG("op_name <%s> (cmd %p), direction=%d "
-+ "(expected %d, set %s), bufflen=%d, out_bufflen=%d (expected "
-+ "len %d, out expected len %d), flags=0x%x", cmd->op_name, cmd,
-+ cmd->data_direction, cmd->expected_data_direction,
-+ scst_cmd_is_expected_set(cmd) ? "yes" : "no",
-+ cmd->bufflen, cmd->out_bufflen, cmd->expected_transfer_len,
-+ cmd->expected_out_transfer_len, cmd->op_flags);
-+
-+ res = 0;
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_err:
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ res = -1;
-+ goto out;
-+}
-+
-+#ifndef CONFIG_SCST_USE_EXPECTED_VALUES
-+static bool scst_is_allowed_to_mismatch_cmd(struct scst_cmd *cmd)
-+{
-+ bool res = false;
-+
-+ /* VERIFY commands with BYTCHK unset shouldn't fail here */
-+ if ((cmd->op_flags & SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED) &&
-+ (cmd->cdb[1] & BYTCHK) == 0) {
-+ res = true;
-+ goto out;
-+ }
-+
-+ switch (cmd->cdb[0]) {
-+ case TEST_UNIT_READY:
-+ /* Crazy VMware people sometimes do TUR with READ direction */
-+ if ((cmd->expected_data_direction == SCST_DATA_READ) ||
-+ (cmd->expected_data_direction == SCST_DATA_NONE))
-+ res = true;
-+ break;
-+ }
-+
-+out:
-+ return res;
-+}
-+#endif
-+
-+static int scst_parse_cmd(struct scst_cmd *cmd)
-+{
-+ int res = SCST_CMD_STATE_RES_CONT_SAME;
-+ int state;
-+ struct scst_device *dev = cmd->dev;
-+ int orig_bufflen = cmd->bufflen;
-+
-+ TRACE_ENTRY();
-+
-+ if (likely(!scst_is_cmd_fully_local(cmd))) {
-+ if (unlikely(!dev->handler->parse_atomic &&
-+ scst_cmd_atomic(cmd))) {
-+ /*
-+ * It shouldn't be because of the SCST_TGT_DEV_AFTER_*
-+ * optimization.
-+ */
-+ TRACE_MGMT_DBG("Dev handler %s parse() needs thread "
-+ "context, rescheduling", dev->handler->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+
-+ TRACE_DBG("Calling dev handler %s parse(%p)",
-+ dev->handler->name, cmd);
-+ TRACE_BUFF_FLAG(TRACE_SND_BOT, "Parsing: ",
-+ cmd->cdb, cmd->cdb_len);
-+ scst_set_cur_start(cmd);
-+ state = dev->handler->parse(cmd);
-+ /* Caution: cmd can be already dead here */
-+ TRACE_DBG("Dev handler %s parse() returned %d",
-+ dev->handler->name, state);
-+
-+ switch (state) {
-+ case SCST_CMD_STATE_NEED_THREAD_CTX:
-+ scst_set_parse_time(cmd);
-+ TRACE_DBG("Dev handler %s parse() requested thread "
-+ "context, rescheduling", dev->handler->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+
-+ case SCST_CMD_STATE_STOP:
-+ TRACE_DBG("Dev handler %s parse() requested stop "
-+ "processing", dev->handler->name);
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+ goto out;
-+ }
-+
-+ scst_set_parse_time(cmd);
-+
-+ if (state == SCST_CMD_STATE_DEFAULT)
-+ state = SCST_CMD_STATE_PREPARE_SPACE;
-+ } else
-+ state = SCST_CMD_STATE_PREPARE_SPACE;
-+
-+ if (unlikely(state == SCST_CMD_STATE_PRE_XMIT_RESP))
-+ goto set_res;
-+
-+ if (unlikely(!(cmd->op_flags & SCST_INFO_VALID))) {
-+#ifdef CONFIG_SCST_USE_EXPECTED_VALUES
-+ if (scst_cmd_is_expected_set(cmd)) {
-+ TRACE(TRACE_MINOR, "Using initiator supplied values: "
-+ "direction %d, transfer_len %d/%d",
-+ cmd->expected_data_direction,
-+ cmd->expected_transfer_len,
-+ cmd->expected_out_transfer_len);
-+ cmd->data_direction = cmd->expected_data_direction;
-+ cmd->bufflen = cmd->expected_transfer_len;
-+ cmd->out_bufflen = cmd->expected_out_transfer_len;
-+ } else {
-+ PRINT_ERROR("Unknown opcode 0x%02x for %s and "
-+ "target %s not supplied expected values",
-+ cmd->cdb[0], dev->handler->name, cmd->tgtt->name);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_opcode));
-+ goto out_done;
-+ }
-+#else
-+ /*
-+ * Let's ignore reporting T10/04-262r7 16-byte and 12-byte ATA
-+ * pass-thru commands to not pollute logs (udev(?) checks them
-+ * for some reason). If somebody has their description, please,
-+ * update scst_scsi_op_table.
-+ */
-+ if ((cmd->cdb[0] != 0x85) && (cmd->cdb[0] != 0xa1))
-+ PRINT_ERROR("Refusing unknown opcode %x", cmd->cdb[0]);
-+ else
-+ TRACE(TRACE_MINOR, "Refusing unknown opcode %x",
-+ cmd->cdb[0]);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_opcode));
-+ goto out_done;
-+#endif
-+ }
-+
-+ if (unlikely(cmd->cdb_len == 0)) {
-+ PRINT_ERROR("Unable to get CDB length for "
-+ "opcode 0x%02x. Returning INVALID "
-+ "OPCODE", cmd->cdb[0]);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_opcode));
-+ goto out_done;
-+ }
-+
-+ EXTRACHECKS_BUG_ON(cmd->cdb_len == 0);
-+
-+ TRACE(TRACE_SCSI, "op_name <%s> (cmd %p), direction=%d "
-+ "(expected %d, set %s), bufflen=%d, out_bufflen=%d, (expected "
-+ "len %d, out expected len %d), flags=%x", cmd->op_name, cmd,
-+ cmd->data_direction, cmd->expected_data_direction,
-+ scst_cmd_is_expected_set(cmd) ? "yes" : "no",
-+ cmd->bufflen, cmd->out_bufflen, cmd->expected_transfer_len,
-+ cmd->expected_out_transfer_len, cmd->op_flags);
-+
-+ if (unlikely((cmd->op_flags & SCST_UNKNOWN_LENGTH) != 0)) {
-+ if (scst_cmd_is_expected_set(cmd)) {
-+ /*
-+ * Command data length can't be easily
-+ * determined from the CDB. ToDo, all such
-+ * commands processing should be fixed. Until
-+ * it's done, get the length from the supplied
-+ * expected value, but limit it to some
-+ * reasonable value (15MB).
-+ */
-+ cmd->bufflen = min(cmd->expected_transfer_len,
-+ 15*1024*1024);
-+ if (cmd->data_direction == SCST_DATA_BIDI)
-+ cmd->out_bufflen = min(cmd->expected_out_transfer_len,
-+ 15*1024*1024);
-+ cmd->op_flags &= ~SCST_UNKNOWN_LENGTH;
-+ } else {
-+ PRINT_ERROR("Unknown data transfer length for opcode "
-+ "0x%x (handler %s, target %s)", cmd->cdb[0],
-+ dev->handler->name, cmd->tgtt->name);
-+ PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_message));
-+ goto out_done;
-+ }
-+ }
-+
-+ if (unlikely(cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_NACA_BIT)) {
-+ PRINT_ERROR("NACA bit in control byte CDB is not supported "
-+ "(opcode 0x%02x)", cmd->cdb[0]);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
-+ goto out_done;
-+ }
-+
-+ if (unlikely(cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_LINK_BIT)) {
-+ PRINT_ERROR("Linked commands are not supported "
-+ "(opcode 0x%02x)", cmd->cdb[0]);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
-+ goto out_done;
-+ }
-+
-+ if (cmd->dh_data_buf_alloced &&
-+ unlikely((orig_bufflen > cmd->bufflen))) {
-+ PRINT_ERROR("Dev handler supplied data buffer (size %d), "
-+ "is less, than required (size %d)", cmd->bufflen,
-+ orig_bufflen);
-+ PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len);
-+ goto out_hw_error;
-+ }
-+
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ if ((cmd->bufflen != 0) &&
-+ ((cmd->data_direction == SCST_DATA_NONE) ||
-+ ((cmd->sg == NULL) && (state > SCST_CMD_STATE_PREPARE_SPACE)))) {
-+ PRINT_ERROR("Dev handler %s parse() returned "
-+ "invalid cmd data_direction %d, bufflen %d, state %d "
-+ "or sg %p (opcode 0x%x)", dev->handler->name,
-+ cmd->data_direction, cmd->bufflen, state, cmd->sg,
-+ cmd->cdb[0]);
-+ PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len);
-+ goto out_hw_error;
-+ }
-+#endif
-+
-+ if (scst_cmd_is_expected_set(cmd)) {
-+#ifdef CONFIG_SCST_USE_EXPECTED_VALUES
-+ if (unlikely((cmd->data_direction != cmd->expected_data_direction) ||
-+ (cmd->bufflen != cmd->expected_transfer_len) ||
-+ (cmd->out_bufflen != cmd->expected_out_transfer_len))) {
-+ TRACE(TRACE_MINOR, "Expected values don't match "
-+ "decoded ones: data_direction %d, "
-+ "expected_data_direction %d, "
-+ "bufflen %d, expected_transfer_len %d, "
-+ "out_bufflen %d, expected_out_transfer_len %d",
-+ cmd->data_direction,
-+ cmd->expected_data_direction,
-+ cmd->bufflen, cmd->expected_transfer_len,
-+ cmd->out_bufflen, cmd->expected_out_transfer_len);
-+ PRINT_BUFF_FLAG(TRACE_MINOR, "Suspicious CDB",
-+ cmd->cdb, cmd->cdb_len);
-+ cmd->data_direction = cmd->expected_data_direction;
-+ cmd->bufflen = cmd->expected_transfer_len;
-+ cmd->out_bufflen = cmd->expected_out_transfer_len;
-+ cmd->resid_possible = 1;
-+ }
-+#else
-+ if (unlikely(cmd->data_direction !=
-+ cmd->expected_data_direction)) {
-+ if (((cmd->expected_data_direction != SCST_DATA_NONE) ||
-+ (cmd->bufflen != 0)) &&
-+ !scst_is_allowed_to_mismatch_cmd(cmd)) {
-+ PRINT_ERROR("Expected data direction %d for "
-+ "opcode 0x%02x (handler %s, target %s) "
-+ "doesn't match decoded value %d",
-+ cmd->expected_data_direction,
-+ cmd->cdb[0], dev->handler->name,
-+ cmd->tgtt->name, cmd->data_direction);
-+ PRINT_BUFFER("Failed CDB", cmd->cdb,
-+ cmd->cdb_len);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_message));
-+ goto out_done;
-+ }
-+ }
-+ if (unlikely(cmd->bufflen != cmd->expected_transfer_len)) {
-+ TRACE(TRACE_MINOR, "Warning: expected "
-+ "transfer length %d for opcode 0x%02x "
-+ "(handler %s, target %s) doesn't match "
-+ "decoded value %d",
-+ cmd->expected_transfer_len, cmd->cdb[0],
-+ dev->handler->name, cmd->tgtt->name,
-+ cmd->bufflen);
-+ PRINT_BUFF_FLAG(TRACE_MINOR, "Suspicious CDB",
-+ cmd->cdb, cmd->cdb_len);
-+ if ((cmd->data_direction & SCST_DATA_READ) ||
-+ (cmd->data_direction & SCST_DATA_WRITE))
-+ cmd->resid_possible = 1;
-+ }
-+ if (unlikely(cmd->out_bufflen != cmd->expected_out_transfer_len)) {
-+ TRACE(TRACE_MINOR, "Warning: expected bidirectional OUT "
-+ "transfer length %d for opcode 0x%02x "
-+ "(handler %s, target %s) doesn't match "
-+ "decoded value %d",
-+ cmd->expected_out_transfer_len, cmd->cdb[0],
-+ dev->handler->name, cmd->tgtt->name,
-+ cmd->out_bufflen);
-+ PRINT_BUFF_FLAG(TRACE_MINOR, "Suspicious CDB",
-+ cmd->cdb, cmd->cdb_len);
-+ cmd->resid_possible = 1;
-+ }
-+#endif
-+ }
-+
-+ if (unlikely(cmd->data_direction == SCST_DATA_UNKNOWN)) {
-+ PRINT_ERROR("Unknown data direction. Opcode 0x%x, handler %s, "
-+ "target %s", cmd->cdb[0], dev->handler->name,
-+ cmd->tgtt->name);
-+ PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len);
-+ goto out_hw_error;
-+ }
-+
-+set_res:
-+ if (cmd->data_len == -1)
-+ cmd->data_len = cmd->bufflen;
-+
-+ if (cmd->bufflen == 0) {
-+ /*
-+ * According to SPC bufflen 0 for data transfer commands isn't
-+ * an error, so we need to fix the transfer direction.
-+ */
-+ cmd->data_direction = SCST_DATA_NONE;
-+ }
-+
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ switch (state) {
-+ case SCST_CMD_STATE_PREPARE_SPACE:
-+ case SCST_CMD_STATE_PARSE:
-+ case SCST_CMD_STATE_RDY_TO_XFER:
-+ case SCST_CMD_STATE_TGT_PRE_EXEC:
-+ case SCST_CMD_STATE_SEND_FOR_EXEC:
-+ case SCST_CMD_STATE_START_EXEC:
-+ case SCST_CMD_STATE_LOCAL_EXEC:
-+ case SCST_CMD_STATE_REAL_EXEC:
-+ case SCST_CMD_STATE_PRE_DEV_DONE:
-+ case SCST_CMD_STATE_DEV_DONE:
-+ case SCST_CMD_STATE_PRE_XMIT_RESP:
-+ case SCST_CMD_STATE_XMIT_RESP:
-+ case SCST_CMD_STATE_FINISHED:
-+ case SCST_CMD_STATE_FINISHED_INTERNAL:
-+#endif
-+ cmd->state = state;
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ break;
-+
-+ default:
-+ if (state >= 0) {
-+ PRINT_ERROR("Dev handler %s parse() returned "
-+ "invalid cmd state %d (opcode %d)",
-+ dev->handler->name, state, cmd->cdb[0]);
-+ } else {
-+ PRINT_ERROR("Dev handler %s parse() returned "
-+ "error %d (opcode %d)", dev->handler->name,
-+ state, cmd->cdb[0]);
-+ }
-+ goto out_hw_error;
-+ }
-+#endif
-+
-+ if (cmd->resp_data_len == -1) {
-+ if (cmd->data_direction & SCST_DATA_READ)
-+ cmd->resp_data_len = cmd->bufflen;
-+ else
-+ cmd->resp_data_len = 0;
-+ }
-+
-+ /* We already completed (with an error) */
-+ if (unlikely(cmd->completed))
-+ goto out_done;
-+
-+#ifndef CONFIG_SCST_TEST_IO_IN_SIRQ
-+ /*
-+ * We can't allow atomic command on the exec stages. It shouldn't
-+ * be because of the SCST_TGT_DEV_AFTER_* optimization, but during
-+ * parsing data_direction can change, so we need to recheck.
-+ */
-+ if (unlikely(scst_cmd_atomic(cmd) &&
-+ !(cmd->data_direction & SCST_DATA_WRITE))) {
-+ TRACE_DBG_FLAG(TRACE_DEBUG|TRACE_MINOR, "Atomic context and "
-+ "non-WRITE data direction, rescheduling (cmd %p)", cmd);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+#endif
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+
-+out_hw_error:
-+ /* dev_done() will be called as part of the regular cmd's finish */
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
-+
-+out_done:
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+ goto out;
-+}
-+
-+static void scst_set_write_len(struct scst_cmd *cmd)
-+{
-+ TRACE_ENTRY();
-+
-+ EXTRACHECKS_BUG_ON(!(cmd->data_direction & SCST_DATA_WRITE));
-+
-+ if (cmd->data_direction & SCST_DATA_READ) {
-+ cmd->write_len = cmd->out_bufflen;
-+ cmd->write_sg = &cmd->out_sg;
-+ cmd->write_sg_cnt = &cmd->out_sg_cnt;
-+ } else {
-+ cmd->write_len = cmd->bufflen;
-+ /* write_sg and write_sg_cnt already initialized correctly */
-+ }
-+
-+ TRACE_MEM("cmd %p, write_len %d, write_sg %p, write_sg_cnt %d, "
-+ "resid_possible %d", cmd, cmd->write_len, *cmd->write_sg,
-+ *cmd->write_sg_cnt, cmd->resid_possible);
-+
-+ if (unlikely(cmd->resid_possible)) {
-+ if (cmd->data_direction & SCST_DATA_READ) {
-+ cmd->write_len = min(cmd->out_bufflen,
-+ cmd->expected_out_transfer_len);
-+ if (cmd->write_len == cmd->out_bufflen)
-+ goto out;
-+ } else {
-+ cmd->write_len = min(cmd->bufflen,
-+ cmd->expected_transfer_len);
-+ if (cmd->write_len == cmd->bufflen)
-+ goto out;
-+ }
-+ scst_limit_sg_write_len(cmd);
-+ }
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+static int scst_prepare_space(struct scst_cmd *cmd)
-+{
-+ int r = 0, res = SCST_CMD_STATE_RES_CONT_SAME;
-+ struct scst_device *dev = cmd->dev;
-+
-+ TRACE_ENTRY();
-+
-+ if (cmd->data_direction == SCST_DATA_NONE)
-+ goto done;
-+
-+ if (likely(!scst_is_cmd_fully_local(cmd)) &&
-+ (dev->handler->alloc_data_buf != NULL)) {
-+ int state;
-+
-+ if (unlikely(!dev->handler->alloc_data_buf_atomic &&
-+ scst_cmd_atomic(cmd))) {
-+ /*
-+ * It shouldn't be because of the SCST_TGT_DEV_AFTER_*
-+ * optimization.
-+ */
-+ TRACE_MGMT_DBG("Dev handler %s alloc_data_buf() needs "
-+ "thread context, rescheduling",
-+ dev->handler->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+
-+ TRACE_DBG("Calling dev handler %s alloc_data_buf(%p)",
-+ dev->handler->name, cmd);
-+ scst_set_cur_start(cmd);
-+ state = dev->handler->alloc_data_buf(cmd);
-+ /* Caution: cmd can be already dead here */
-+ TRACE_DBG("Dev handler %s alloc_data_buf() returned %d",
-+ dev->handler->name, state);
-+
-+ switch (state) {
-+ case SCST_CMD_STATE_NEED_THREAD_CTX:
-+ scst_set_alloc_buf_time(cmd);
-+ TRACE_DBG("Dev handler %s alloc_data_buf() requested "
-+ "thread context, rescheduling",
-+ dev->handler->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+
-+ case SCST_CMD_STATE_STOP:
-+ TRACE_DBG("Dev handler %s alloc_data_buf() requested "
-+ "stop processing", dev->handler->name);
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+ goto out;
-+ }
-+
-+ scst_set_alloc_buf_time(cmd);
-+
-+ if (unlikely(state != SCST_CMD_STATE_DEFAULT)) {
-+ cmd->state = state;
-+ goto out;
-+ }
-+ }
-+
-+ if (cmd->tgt_need_alloc_data_buf) {
-+ int orig_bufflen = cmd->bufflen;
-+
-+ TRACE_MEM("Custom tgt data buf allocation requested (cmd %p)",
-+ cmd);
-+
-+ scst_set_cur_start(cmd);
-+ r = cmd->tgtt->alloc_data_buf(cmd);
-+ scst_set_alloc_buf_time(cmd);
-+
-+ if (r > 0)
-+ goto alloc;
-+ else if (r == 0) {
-+ if (unlikely(cmd->bufflen == 0)) {
-+ /* See comment in scst_alloc_space() */
-+ if (cmd->sg == NULL)
-+ goto alloc;
-+ }
-+
-+ cmd->tgt_data_buf_alloced = 1;
-+
-+ if (unlikely(orig_bufflen < cmd->bufflen)) {
-+ PRINT_ERROR("Target driver allocated data "
-+ "buffer (size %d), is less, than "
-+ "required (size %d)", orig_bufflen,
-+ cmd->bufflen);
-+ goto out_error;
-+ }
-+ TRACE_MEM("tgt_data_buf_alloced (cmd %p)", cmd);
-+ } else
-+ goto check;
-+ }
-+
-+alloc:
-+ if (!cmd->tgt_data_buf_alloced && !cmd->dh_data_buf_alloced) {
-+ r = scst_alloc_space(cmd);
-+ } else if (cmd->dh_data_buf_alloced && !cmd->tgt_data_buf_alloced) {
-+ TRACE_MEM("dh_data_buf_alloced set (cmd %p)", cmd);
-+ r = 0;
-+ } else if (cmd->tgt_data_buf_alloced && !cmd->dh_data_buf_alloced) {
-+ TRACE_MEM("tgt_data_buf_alloced set (cmd %p)", cmd);
-+ cmd->sg = cmd->tgt_sg;
-+ cmd->sg_cnt = cmd->tgt_sg_cnt;
-+ cmd->out_sg = cmd->tgt_out_sg;
-+ cmd->out_sg_cnt = cmd->tgt_out_sg_cnt;
-+ r = 0;
-+ } else {
-+ TRACE_MEM("Both *_data_buf_alloced set (cmd %p, sg %p, "
-+ "sg_cnt %d, tgt_sg %p, tgt_sg_cnt %d)", cmd, cmd->sg,
-+ cmd->sg_cnt, cmd->tgt_sg, cmd->tgt_sg_cnt);
-+ r = 0;
-+ }
-+
-+check:
-+ if (r != 0) {
-+ if (scst_cmd_atomic(cmd)) {
-+ TRACE_MEM("%s", "Atomic memory allocation failed, "
-+ "rescheduling to the thread");
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ } else
-+ goto out_no_space;
-+ }
-+
-+done:
-+ if (cmd->preprocessing_only) {
-+ cmd->state = SCST_CMD_STATE_PREPROCESSING_DONE;
-+ if (cmd->data_direction & SCST_DATA_WRITE)
-+ scst_set_write_len(cmd);
-+ } else if (cmd->data_direction & SCST_DATA_WRITE) {
-+ cmd->state = SCST_CMD_STATE_RDY_TO_XFER;
-+ scst_set_write_len(cmd);
-+ } else
-+ cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+
-+out_no_space:
-+ TRACE(TRACE_OUT_OF_MEM, "Unable to allocate or build requested buffer "
-+ "(size %d), sending BUSY or QUEUE FULL status", cmd->bufflen);
-+ scst_set_busy(cmd);
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+ goto out;
-+
-+out_error:
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+ goto out;
-+}
-+
-+static int scst_preprocessing_done(struct scst_cmd *cmd)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ EXTRACHECKS_BUG_ON(!cmd->preprocessing_only);
-+
-+ cmd->preprocessing_only = 0;
-+
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+ cmd->state = SCST_CMD_STATE_PREPROCESSING_DONE_CALLED;
-+
-+ TRACE_DBG("Calling preprocessing_done(cmd %p)", cmd);
-+ scst_set_cur_start(cmd);
-+ cmd->tgtt->preprocessing_done(cmd);
-+ TRACE_DBG("%s", "preprocessing_done() returned");
-+
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+/**
-+ * scst_restart_cmd() - restart execution of the command
-+ * @cmd: SCST commands
-+ * @status: completion status
-+ * @pref_context: preferred command execution context
-+ *
-+ * Description:
-+ * Notifies SCST that the driver finished its part of the command's
-+ * preprocessing and it is ready for further processing.
-+ *
-+ * The second argument sets completion status
-+ * (see SCST_PREPROCESS_STATUS_* constants for details)
-+ *
-+ * See also comment for scst_cmd_init_done() for the serialization
-+ * requirements.
-+ */
-+void scst_restart_cmd(struct scst_cmd *cmd, int status,
-+ enum scst_exec_context pref_context)
-+{
-+ TRACE_ENTRY();
-+
-+ scst_set_restart_waiting_time(cmd);
-+
-+ TRACE_DBG("Preferred context: %d", pref_context);
-+ TRACE_DBG("tag=%llu, status=%#x",
-+ (long long unsigned int)scst_cmd_get_tag(cmd),
-+ status);
-+
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ if ((in_irq() || irqs_disabled()) &&
-+ ((pref_context == SCST_CONTEXT_DIRECT) ||
-+ (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) {
-+ PRINT_ERROR("Wrong context %d in IRQ from target %s, use "
-+ "SCST_CONTEXT_THREAD instead", pref_context,
-+ cmd->tgtt->name);
-+ dump_stack();
-+ pref_context = SCST_CONTEXT_THREAD;
-+ }
-+#endif
-+
-+ switch (status) {
-+ case SCST_PREPROCESS_STATUS_SUCCESS:
-+ if (cmd->data_direction & SCST_DATA_WRITE)
-+ cmd->state = SCST_CMD_STATE_RDY_TO_XFER;
-+ else
-+ cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
-+ if (cmd->set_sn_on_restart_cmd)
-+ scst_cmd_set_sn(cmd);
-+#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
-+ if (cmd->op_flags & SCST_TEST_IO_IN_SIRQ_ALLOWED)
-+ break;
-+#endif
-+ /* Small context optimization */
-+ if ((pref_context == SCST_CONTEXT_TASKLET) ||
-+ (pref_context == SCST_CONTEXT_DIRECT_ATOMIC) ||
-+ ((pref_context == SCST_CONTEXT_SAME) &&
-+ scst_cmd_atomic(cmd)))
-+ pref_context = SCST_CONTEXT_THREAD;
-+ break;
-+
-+ case SCST_PREPROCESS_STATUS_ERROR_SENSE_SET:
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ pref_context = SCST_CONTEXT_THREAD;
-+ break;
-+
-+ case SCST_PREPROCESS_STATUS_ERROR_FATAL:
-+ set_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags);
-+ /* go through */
-+ case SCST_PREPROCESS_STATUS_ERROR:
-+ if (cmd->sense != NULL)
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ pref_context = SCST_CONTEXT_THREAD;
-+ break;
-+
-+ default:
-+ PRINT_ERROR("%s() received unknown status %x", __func__,
-+ status);
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ pref_context = SCST_CONTEXT_THREAD;
-+ break;
-+ }
-+
-+ scst_process_redirect_cmd(cmd, pref_context, 1);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL(scst_restart_cmd);
-+
-+static int scst_rdy_to_xfer(struct scst_cmd *cmd)
-+{
-+ int res, rc;
-+ struct scst_tgt_template *tgtt = cmd->tgtt;
-+
-+ TRACE_ENTRY();
-+
-+ if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
-+ TRACE_MGMT_DBG("ABORTED set, aborting cmd %p", cmd);
-+ goto out_dev_done;
-+ }
-+
-+ if ((tgtt->rdy_to_xfer == NULL) || unlikely(cmd->internal)) {
-+ cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
-+#ifndef CONFIG_SCST_TEST_IO_IN_SIRQ
-+ /* We can't allow atomic command on the exec stages */
-+ if (scst_cmd_atomic(cmd)) {
-+ TRACE_DBG("NULL rdy_to_xfer() and atomic context, "
-+ "rescheduling (cmd %p)", cmd);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ } else
-+#endif
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+ goto out;
-+ }
-+
-+ if (unlikely(!tgtt->rdy_to_xfer_atomic && scst_cmd_atomic(cmd))) {
-+ /*
-+ * It shouldn't be because of the SCST_TGT_DEV_AFTER_*
-+ * optimization.
-+ */
-+ TRACE_MGMT_DBG("Target driver %s rdy_to_xfer() needs thread "
-+ "context, rescheduling", tgtt->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+
-+ while (1) {
-+ int finished_cmds = atomic_read(&cmd->tgt->finished_cmds);
-+
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+ cmd->state = SCST_CMD_STATE_DATA_WAIT;
-+
-+ if (tgtt->on_hw_pending_cmd_timeout != NULL) {
-+ struct scst_session *sess = cmd->sess;
-+ cmd->hw_pending_start = jiffies;
-+ cmd->cmd_hw_pending = 1;
-+ if (!test_bit(SCST_SESS_HW_PENDING_WORK_SCHEDULED, &sess->sess_aflags)) {
-+ TRACE_DBG("Sched HW pending work for sess %p "
-+ "(max time %d)", sess,
-+ tgtt->max_hw_pending_time);
-+ set_bit(SCST_SESS_HW_PENDING_WORK_SCHEDULED,
-+ &sess->sess_aflags);
-+ schedule_delayed_work(&sess->hw_pending_work,
-+ tgtt->max_hw_pending_time * HZ);
-+ }
-+ }
-+
-+ scst_set_cur_start(cmd);
-+
-+ TRACE_DBG("Calling rdy_to_xfer(%p)", cmd);
-+#ifdef CONFIG_SCST_DEBUG_RETRY
-+ if (((scst_random() % 100) == 75))
-+ rc = SCST_TGT_RES_QUEUE_FULL;
-+ else
-+#endif
-+ rc = tgtt->rdy_to_xfer(cmd);
-+ TRACE_DBG("rdy_to_xfer() returned %d", rc);
-+
-+ if (likely(rc == SCST_TGT_RES_SUCCESS))
-+ goto out;
-+
-+ scst_set_rdy_to_xfer_time(cmd);
-+
-+ cmd->cmd_hw_pending = 0;
-+
-+ /* Restore the previous state */
-+ cmd->state = SCST_CMD_STATE_RDY_TO_XFER;
-+
-+ switch (rc) {
-+ case SCST_TGT_RES_QUEUE_FULL:
-+ if (scst_queue_retry_cmd(cmd, finished_cmds) == 0)
-+ break;
-+ else
-+ continue;
-+
-+ case SCST_TGT_RES_NEED_THREAD_CTX:
-+ TRACE_DBG("Target driver %s "
-+ "rdy_to_xfer() requested thread "
-+ "context, rescheduling", tgtt->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+
-+ default:
-+ goto out_error_rc;
-+ }
-+ break;
-+ }
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+
-+out_error_rc:
-+ if (rc == SCST_TGT_RES_FATAL_ERROR) {
-+ PRINT_ERROR("Target driver %s rdy_to_xfer() returned "
-+ "fatal error", tgtt->name);
-+ } else {
-+ PRINT_ERROR("Target driver %s rdy_to_xfer() returned invalid "
-+ "value %d", tgtt->name, rc);
-+ }
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
-+
-+out_dev_done:
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+ goto out;
-+}
-+
-+/* No locks, but might be in IRQ */
-+static void scst_process_redirect_cmd(struct scst_cmd *cmd,
-+ enum scst_exec_context context, int check_retries)
-+{
-+ struct scst_tgt *tgt = cmd->tgt;
-+ unsigned long flags;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_DBG("Context: %x", context);
-+
-+ if (check_retries)
-+ scst_check_retries(tgt);
-+
-+ if (context == SCST_CONTEXT_SAME)
-+ context = scst_cmd_atomic(cmd) ? SCST_CONTEXT_DIRECT_ATOMIC :
-+ SCST_CONTEXT_DIRECT;
-+
-+ switch (context) {
-+ case SCST_CONTEXT_DIRECT_ATOMIC:
-+ scst_process_active_cmd(cmd, true);
-+ break;
-+
-+ case SCST_CONTEXT_DIRECT:
-+ scst_process_active_cmd(cmd, false);
-+ break;
-+
-+ case SCST_CONTEXT_TASKLET:
-+ scst_schedule_tasklet(cmd);
-+ break;
-+
-+ default:
-+ PRINT_ERROR("Context %x is unknown, using the thread one",
-+ context);
-+ /* go through */
-+ case SCST_CONTEXT_THREAD:
-+ spin_lock_irqsave(&cmd->cmd_threads->cmd_list_lock, flags);
-+ TRACE_DBG("Adding cmd %p to active cmd list", cmd);
-+ if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
-+ list_add(&cmd->cmd_list_entry,
-+ &cmd->cmd_threads->active_cmd_list);
-+ else
-+ list_add_tail(&cmd->cmd_list_entry,
-+ &cmd->cmd_threads->active_cmd_list);
-+ wake_up(&cmd->cmd_threads->cmd_list_waitQ);
-+ spin_unlock_irqrestore(&cmd->cmd_threads->cmd_list_lock, flags);
-+ break;
-+ }
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/**
-+ * scst_rx_data() - the command's data received
-+ * @cmd: SCST commands
-+ * @status: data receiving completion status
-+ * @pref_context: preferred command execution context
-+ *
-+ * Description:
-+ * Notifies SCST that the driver received all the necessary data
-+ * and the command is ready for further processing.
-+ *
-+ * The second argument sets data receiving completion status
-+ * (see SCST_RX_STATUS_* constants for details)
-+ */
-+void scst_rx_data(struct scst_cmd *cmd, int status,
-+ enum scst_exec_context pref_context)
-+{
-+ TRACE_ENTRY();
-+
-+ scst_set_rdy_to_xfer_time(cmd);
-+
-+ TRACE_DBG("Preferred context: %d", pref_context);
-+ TRACE(TRACE_SCSI, "cmd %p, status %#x", cmd, status);
-+
-+ cmd->cmd_hw_pending = 0;
-+
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ if ((in_irq() || irqs_disabled()) &&
-+ ((pref_context == SCST_CONTEXT_DIRECT) ||
-+ (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) {
-+ PRINT_ERROR("Wrong context %d in IRQ from target %s, use "
-+ "SCST_CONTEXT_THREAD instead", pref_context,
-+ cmd->tgtt->name);
-+ dump_stack();
-+ pref_context = SCST_CONTEXT_THREAD;
-+ }
-+#endif
-+
-+ switch (status) {
-+ case SCST_RX_STATUS_SUCCESS:
-+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
-+ if (trace_flag & TRACE_RCV_BOT) {
-+ int i, j;
-+ struct scatterlist *sg;
-+ if (cmd->out_sg != NULL)
-+ sg = cmd->out_sg;
-+ else if (cmd->tgt_out_sg != NULL)
-+ sg = cmd->tgt_out_sg;
-+ else if (cmd->tgt_sg != NULL)
-+ sg = cmd->tgt_sg;
-+ else
-+ sg = cmd->sg;
-+ if (sg != NULL) {
-+ TRACE_RECV_BOT("RX data for cmd %p "
-+ "(sg_cnt %d, sg %p, sg[0].page %p)",
-+ cmd, cmd->tgt_sg_cnt, sg,
-+ (void *)sg_page(&sg[0]));
-+ for (i = 0, j = 0; i < cmd->tgt_sg_cnt; ++i, ++j) {
-+ if (unlikely(sg_is_chain(&sg[j]))) {
-+ sg = sg_chain_ptr(&sg[j]);
-+ j = 0;
-+ }
-+ PRINT_BUFF_FLAG(TRACE_RCV_BOT, "RX sg",
-+ sg_virt(&sg[j]), sg[j].length);
-+ }
-+ }
-+ }
-+#endif
-+ cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
-+
-+#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
-+ if (cmd->op_flags & SCST_TEST_IO_IN_SIRQ_ALLOWED)
-+ break;
-+#endif
-+
-+ /* Small context optimization */
-+ if ((pref_context == SCST_CONTEXT_TASKLET) ||
-+ (pref_context == SCST_CONTEXT_DIRECT_ATOMIC) ||
-+ ((pref_context == SCST_CONTEXT_SAME) &&
-+ scst_cmd_atomic(cmd)))
-+ pref_context = SCST_CONTEXT_THREAD;
-+ break;
-+
-+ case SCST_RX_STATUS_ERROR_SENSE_SET:
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ pref_context = SCST_CONTEXT_THREAD;
-+ break;
-+
-+ case SCST_RX_STATUS_ERROR_FATAL:
-+ set_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags);
-+ /* go through */
-+ case SCST_RX_STATUS_ERROR:
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ pref_context = SCST_CONTEXT_THREAD;
-+ break;
-+
-+ default:
-+ PRINT_ERROR("scst_rx_data() received unknown status %x",
-+ status);
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ pref_context = SCST_CONTEXT_THREAD;
-+ break;
-+ }
-+
-+ scst_process_redirect_cmd(cmd, pref_context, 1);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL(scst_rx_data);
-+
-+static int scst_tgt_pre_exec(struct scst_cmd *cmd)
-+{
-+ int res = SCST_CMD_STATE_RES_CONT_SAME, rc;
-+
-+ TRACE_ENTRY();
-+
-+ if (unlikely(cmd->resid_possible)) {
-+ if (cmd->data_direction & SCST_DATA_WRITE) {
-+ bool do_zero = false;
-+ if (cmd->data_direction & SCST_DATA_READ) {
-+ if (cmd->write_len != cmd->out_bufflen)
-+ do_zero = true;
-+ } else {
-+ if (cmd->write_len != cmd->bufflen)
-+ do_zero = true;
-+ }
-+ if (do_zero) {
-+ scst_check_restore_sg_buff(cmd);
-+ scst_zero_write_rest(cmd);
-+ }
-+ }
-+ }
-+
-+ cmd->state = SCST_CMD_STATE_SEND_FOR_EXEC;
-+
-+ if ((cmd->tgtt->pre_exec == NULL) || unlikely(cmd->internal))
-+ goto out;
-+
-+ TRACE_DBG("Calling pre_exec(%p)", cmd);
-+ scst_set_cur_start(cmd);
-+ rc = cmd->tgtt->pre_exec(cmd);
-+ scst_set_pre_exec_time(cmd);
-+ TRACE_DBG("pre_exec() returned %d", rc);
-+
-+ if (unlikely(rc != SCST_PREPROCESS_STATUS_SUCCESS)) {
-+ switch (rc) {
-+ case SCST_PREPROCESS_STATUS_ERROR_SENSE_SET:
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ break;
-+ case SCST_PREPROCESS_STATUS_ERROR_FATAL:
-+ set_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags);
-+ /* go through */
-+ case SCST_PREPROCESS_STATUS_ERROR:
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ break;
-+ default:
-+ BUG();
-+ break;
-+ }
-+ }
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static void scst_do_cmd_done(struct scst_cmd *cmd, int result,
-+ const uint8_t *rq_sense, int rq_sense_len, int resid)
-+{
-+ TRACE_ENTRY();
-+
-+ scst_set_exec_time(cmd);
-+
-+ cmd->status = result & 0xff;
-+ cmd->msg_status = msg_byte(result);
-+ cmd->host_status = host_byte(result);
-+ cmd->driver_status = driver_byte(result);
-+ if (unlikely(resid != 0)) {
-+ if ((cmd->data_direction & SCST_DATA_READ) &&
-+ (resid > 0) && (resid < cmd->resp_data_len))
-+ scst_set_resp_data_len(cmd, cmd->resp_data_len - resid);
-+ /*
-+ * We ignore write direction residue, because from the
-+ * initiator's POV we already transferred all the data.
-+ */
-+ }
-+
-+ if (unlikely(cmd->status == SAM_STAT_CHECK_CONDITION)) {
-+ /* We might have double reset UA here */
-+ cmd->dbl_ua_orig_resp_data_len = cmd->resp_data_len;
-+ cmd->dbl_ua_orig_data_direction = cmd->data_direction;
-+
-+ scst_alloc_set_sense(cmd, 1, rq_sense, rq_sense_len);
-+ }
-+
-+ TRACE(TRACE_SCSI, "cmd %p, result %x, cmd->status %x, resid %d, "
-+ "cmd->msg_status %x, cmd->host_status %x, "
-+ "cmd->driver_status %x", cmd, result, cmd->status, resid,
-+ cmd->msg_status, cmd->host_status, cmd->driver_status);
-+
-+ cmd->completed = 1;
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/* For small context optimization */
-+static inline enum scst_exec_context scst_optimize_post_exec_context(
-+ struct scst_cmd *cmd, enum scst_exec_context context)
-+{
-+ if (((context == SCST_CONTEXT_SAME) && scst_cmd_atomic(cmd)) ||
-+ (context == SCST_CONTEXT_TASKLET) ||
-+ (context == SCST_CONTEXT_DIRECT_ATOMIC)) {
-+ if (!test_bit(SCST_TGT_DEV_AFTER_EXEC_ATOMIC,
-+ &cmd->tgt_dev->tgt_dev_flags))
-+ context = SCST_CONTEXT_THREAD;
-+ }
-+ return context;
-+}
-+
-+/**
-+ * scst_pass_through_cmd_done - done callback for pass-through commands
-+ * @data: private opaque data
-+ * @sense: pointer to the sense data, if any
-+ * @result: command's execution result
-+ * @resid: residual, if any
-+ */
-+void scst_pass_through_cmd_done(void *data, char *sense, int result, int resid)
-+{
-+ struct scst_cmd *cmd;
-+
-+ TRACE_ENTRY();
-+
-+ cmd = (struct scst_cmd *)data;
-+ if (cmd == NULL)
-+ goto out;
-+
-+ scst_do_cmd_done(cmd, result, sense, SCSI_SENSE_BUFFERSIZE, resid);
-+
-+ cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
-+
-+ scst_process_redirect_cmd(cmd,
-+ scst_optimize_post_exec_context(cmd, scst_estimate_context()), 0);
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(scst_pass_through_cmd_done);
-+
-+static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state,
-+ enum scst_exec_context pref_context)
-+{
-+ TRACE_ENTRY();
-+
-+ EXTRACHECKS_BUG_ON(cmd->pr_abort_counter != NULL);
-+
-+ scst_set_exec_time(cmd);
-+
-+ TRACE(TRACE_SCSI, "cmd %p, status %x, msg_status %x, host_status %x, "
-+ "driver_status %x, resp_data_len %d", cmd, cmd->status,
-+ cmd->msg_status, cmd->host_status, cmd->driver_status,
-+ cmd->resp_data_len);
-+
-+ if (next_state == SCST_CMD_STATE_DEFAULT)
-+ next_state = SCST_CMD_STATE_PRE_DEV_DONE;
-+
-+#if defined(CONFIG_SCST_DEBUG)
-+ if (next_state == SCST_CMD_STATE_PRE_DEV_DONE) {
-+ if ((trace_flag & TRACE_RCV_TOP) && (cmd->sg != NULL)) {
-+ int i, j;
-+ struct scatterlist *sg = cmd->sg;
-+ TRACE_RECV_TOP("Exec'd %d S/G(s) at %p sg[0].page at "
-+ "%p", cmd->sg_cnt, sg, (void *)sg_page(&sg[0]));
-+ for (i = 0, j = 0; i < cmd->sg_cnt; ++i, ++j) {
-+ if (unlikely(sg_is_chain(&sg[j]))) {
-+ sg = sg_chain_ptr(&sg[j]);
-+ j = 0;
-+ }
-+ TRACE_BUFF_FLAG(TRACE_RCV_TOP,
-+ "Exec'd sg", sg_virt(&sg[j]),
-+ sg[j].length);
-+ }
-+ }
-+ }
-+#endif
-+
-+ cmd->state = next_state;
-+
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ if ((next_state != SCST_CMD_STATE_PRE_DEV_DONE) &&
-+ (next_state != SCST_CMD_STATE_PRE_XMIT_RESP) &&
-+ (next_state != SCST_CMD_STATE_FINISHED) &&
-+ (next_state != SCST_CMD_STATE_FINISHED_INTERNAL)) {
-+ PRINT_ERROR("%s() received invalid cmd state %d (opcode %d)",
-+ __func__, next_state, cmd->cdb[0]);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ }
-+#endif
-+ pref_context = scst_optimize_post_exec_context(cmd, pref_context);
-+ scst_process_redirect_cmd(cmd, pref_context, 0);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+static int scst_report_luns_local(struct scst_cmd *cmd)
-+{
-+ int res = SCST_EXEC_COMPLETED, rc;
-+ int dev_cnt = 0;
-+ int buffer_size;
-+ int i;
-+ struct scst_tgt_dev *tgt_dev = NULL;
-+ uint8_t *buffer;
-+ int offs, overflow = 0;
-+
-+ TRACE_ENTRY();
-+
-+ rc = scst_check_local_events(cmd);
-+ if (unlikely(rc != 0))
-+ goto out_done;
-+
-+ cmd->status = 0;
-+ cmd->msg_status = 0;
-+ cmd->host_status = DID_OK;
-+ cmd->driver_status = 0;
-+
-+ if ((cmd->cdb[2] != 0) && (cmd->cdb[2] != 2)) {
-+ PRINT_ERROR("Unsupported SELECT REPORT value %x in REPORT "
-+ "LUNS command", cmd->cdb[2]);
-+ goto out_err;
-+ }
-+
-+ buffer_size = scst_get_buf_full(cmd, &buffer);
-+ if (unlikely(buffer_size == 0))
-+ goto out_compl;
-+ else if (unlikely(buffer_size < 0))
-+ goto out_hw_err;
-+
-+ if (buffer_size < 16)
-+ goto out_put_err;
-+
-+ memset(buffer, 0, buffer_size);
-+ offs = 8;
-+
-+ /*
-+ * cmd won't allow to suspend activities, so we can access
-+ * sess->sess_tgt_dev_list without any additional protection.
-+ */
-+ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
-+ struct list_head *head = &cmd->sess->sess_tgt_dev_list[i];
-+ list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
-+ if (!overflow) {
-+ if ((buffer_size - offs) < 8) {
-+ overflow = 1;
-+ goto inc_dev_cnt;
-+ }
-+ *(__force __be64 *)&buffer[offs]
-+ = scst_pack_lun(tgt_dev->lun,
-+ cmd->sess->acg->addr_method);
-+ offs += 8;
-+ }
-+inc_dev_cnt:
-+ dev_cnt++;
-+ }
-+ }
-+
-+ /* Set the response header */
-+ dev_cnt *= 8;
-+ buffer[0] = (dev_cnt >> 24) & 0xff;
-+ buffer[1] = (dev_cnt >> 16) & 0xff;
-+ buffer[2] = (dev_cnt >> 8) & 0xff;
-+ buffer[3] = dev_cnt & 0xff;
-+
-+ scst_put_buf_full(cmd, buffer);
-+
-+ dev_cnt += 8;
-+ if (dev_cnt < cmd->resp_data_len)
-+ scst_set_resp_data_len(cmd, dev_cnt);
-+
-+out_compl:
-+ cmd->completed = 1;
-+
-+ /* Clear left sense_reported_luns_data_changed UA, if any. */
-+
-+ /*
-+ * cmd won't allow to suspend activities, so we can access
-+ * sess->sess_tgt_dev_list without any additional protection.
-+ */
-+ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
-+ struct list_head *head = &cmd->sess->sess_tgt_dev_list[i];
-+
-+ list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
-+ struct scst_tgt_dev_UA *ua;
-+
-+ spin_lock_bh(&tgt_dev->tgt_dev_lock);
-+ list_for_each_entry(ua, &tgt_dev->UA_list,
-+ UA_list_entry) {
-+ if (scst_analyze_sense(ua->UA_sense_buffer,
-+ ua->UA_valid_sense_len,
-+ SCST_SENSE_ALL_VALID,
-+ SCST_LOAD_SENSE(scst_sense_reported_luns_data_changed))) {
-+ TRACE_MGMT_DBG("Freeing not needed "
-+ "REPORTED LUNS DATA CHANGED UA "
-+ "%p", ua);
-+ scst_tgt_dev_del_free_UA(tgt_dev, ua);
-+ break;
-+ }
-+ }
-+ spin_unlock_bh(&tgt_dev->tgt_dev_lock);
-+ }
-+ }
-+
-+out_done:
-+ /* Report the result */
-+ cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_put_err:
-+ scst_put_buf_full(cmd, buffer);
-+
-+out_err:
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
-+ goto out_compl;
-+
-+out_hw_err:
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ goto out_compl;
-+}
-+
-+static int scst_request_sense_local(struct scst_cmd *cmd)
-+{
-+ int res = SCST_EXEC_COMPLETED, rc;
-+ struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
-+ uint8_t *buffer;
-+ int buffer_size = 0, sl = 0;
-+
-+ TRACE_ENTRY();
-+
-+ rc = scst_check_local_events(cmd);
-+ if (unlikely(rc != 0))
-+ goto out_done;
-+
-+ cmd->status = 0;
-+ cmd->msg_status = 0;
-+ cmd->host_status = DID_OK;
-+ cmd->driver_status = 0;
-+
-+ spin_lock_bh(&tgt_dev->tgt_dev_lock);
-+
-+ if (tgt_dev->tgt_dev_valid_sense_len == 0)
-+ goto out_unlock_not_completed;
-+
-+ TRACE(TRACE_SCSI, "%s: Returning stored sense", cmd->op_name);
-+
-+ buffer_size = scst_get_buf_full(cmd, &buffer);
-+ if (unlikely(buffer_size == 0))
-+ goto out_unlock_compl;
-+ else if (unlikely(buffer_size < 0))
-+ goto out_unlock_hw_err;
-+
-+ memset(buffer, 0, buffer_size);
-+
-+ if (((tgt_dev->tgt_dev_sense[0] == 0x70) ||
-+ (tgt_dev->tgt_dev_sense[0] == 0x71)) && (cmd->cdb[1] & 1)) {
-+ PRINT_WARNING("%s: Fixed format of the saved sense, but "
-+ "descriptor format requested. Conversion will "
-+ "truncated data", cmd->op_name);
-+ PRINT_BUFFER("Original sense", tgt_dev->tgt_dev_sense,
-+ tgt_dev->tgt_dev_valid_sense_len);
-+
-+ buffer_size = min(SCST_STANDARD_SENSE_LEN, buffer_size);
-+ sl = scst_set_sense(buffer, buffer_size, true,
-+ tgt_dev->tgt_dev_sense[2], tgt_dev->tgt_dev_sense[12],
-+ tgt_dev->tgt_dev_sense[13]);
-+ } else if (((tgt_dev->tgt_dev_sense[0] == 0x72) ||
-+ (tgt_dev->tgt_dev_sense[0] == 0x73)) && !(cmd->cdb[1] & 1)) {
-+ PRINT_WARNING("%s: Descriptor format of the "
-+ "saved sense, but fixed format requested. Conversion "
-+ "will truncated data", cmd->op_name);
-+ PRINT_BUFFER("Original sense", tgt_dev->tgt_dev_sense,
-+ tgt_dev->tgt_dev_valid_sense_len);
-+
-+ buffer_size = min(SCST_STANDARD_SENSE_LEN, buffer_size);
-+ sl = scst_set_sense(buffer, buffer_size, false,
-+ tgt_dev->tgt_dev_sense[1], tgt_dev->tgt_dev_sense[2],
-+ tgt_dev->tgt_dev_sense[3]);
-+ } else {
-+ if (buffer_size >= tgt_dev->tgt_dev_valid_sense_len)
-+ sl = tgt_dev->tgt_dev_valid_sense_len;
-+ else {
-+ sl = buffer_size;
-+ TRACE(TRACE_MINOR, "%s: Being returned sense truncated "
-+ "to size %d (needed %d)", cmd->op_name,
-+ buffer_size, tgt_dev->tgt_dev_valid_sense_len);
-+ }
-+ memcpy(buffer, tgt_dev->tgt_dev_sense, sl);
-+ }
-+
-+ scst_put_buf_full(cmd, buffer);
-+
-+ tgt_dev->tgt_dev_valid_sense_len = 0;
-+
-+ spin_unlock_bh(&tgt_dev->tgt_dev_lock);
-+
-+ scst_set_resp_data_len(cmd, sl);
-+
-+out_compl:
-+ cmd->completed = 1;
-+
-+out_done:
-+ /* Report the result */
-+ cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_unlock_hw_err:
-+ spin_unlock_bh(&tgt_dev->tgt_dev_lock);
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ goto out_compl;
-+
-+out_unlock_not_completed:
-+ spin_unlock_bh(&tgt_dev->tgt_dev_lock);
-+ res = SCST_EXEC_NOT_COMPLETED;
-+ goto out;
-+
-+out_unlock_compl:
-+ spin_unlock_bh(&tgt_dev->tgt_dev_lock);
-+ goto out_compl;
-+}
-+
-+static int scst_reserve_local(struct scst_cmd *cmd)
-+{
-+ int res = SCST_EXEC_NOT_COMPLETED, rc;
-+ struct scst_device *dev;
-+ struct scst_tgt_dev *tgt_dev_tmp;
-+
-+ TRACE_ENTRY();
-+
-+ if ((cmd->cdb[0] == RESERVE_10) && (cmd->cdb[2] & SCST_RES_3RDPTY)) {
-+ PRINT_ERROR("RESERVE_10: 3rdPty RESERVE not implemented "
-+ "(lun=%lld)", (long long unsigned int)cmd->lun);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
-+ goto out_done;
-+ }
-+
-+ dev = cmd->dev;
-+
-+ /*
-+ * There's no need to block this device, even for
-+ * SCST_CONTR_MODE_ONE_TASK_SET, or anyhow else protect reservations
-+ * changes, because:
-+ *
-+ * 1. The reservation changes are (rather) atomic, i.e., in contrast
-+ * to persistent reservations, don't have any invalid intermediate
-+ * states during being changed.
-+ *
-+ * 2. It's a duty of initiators to ensure order of regular commands
-+ * around the reservation command either by ORDERED attribute, or by
-+ * queue draining, or etc. For case of SCST_CONTR_MODE_ONE_TASK_SET
-+ * there are no target drivers which can ensure even for ORDERED
-+ * commands order of their delivery, so, because initiators know
-+ * it, also there's no point to do any extra protection actions.
-+ */
-+
-+ rc = scst_pre_check_local_events(cmd);
-+ if (unlikely(rc != 0))
-+ goto out_done;
-+
-+ if (!list_empty(&dev->dev_registrants_list)) {
-+ if (scst_pr_crh_case(cmd))
-+ goto out_completed;
-+ else {
-+ scst_set_cmd_error_status(cmd,
-+ SAM_STAT_RESERVATION_CONFLICT);
-+ goto out_done;
-+ }
-+ }
-+
-+ spin_lock_bh(&dev->dev_lock);
-+
-+ if (test_bit(SCST_TGT_DEV_RESERVED, &cmd->tgt_dev->tgt_dev_flags)) {
-+ spin_unlock_bh(&dev->dev_lock);
-+ scst_set_cmd_error_status(cmd, SAM_STAT_RESERVATION_CONFLICT);
-+ goto out_done;
-+ }
-+
-+ list_for_each_entry(tgt_dev_tmp, &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ if (cmd->tgt_dev != tgt_dev_tmp)
-+ set_bit(SCST_TGT_DEV_RESERVED,
-+ &tgt_dev_tmp->tgt_dev_flags);
-+ }
-+ dev->dev_reserved = 1;
-+
-+ spin_unlock_bh(&dev->dev_lock);
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_completed:
-+ cmd->completed = 1;
-+
-+out_done:
-+ /* Report the result */
-+ cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
-+ res = SCST_EXEC_COMPLETED;
-+ goto out;
-+}
-+
-+static int scst_release_local(struct scst_cmd *cmd)
-+{
-+ int res = SCST_EXEC_NOT_COMPLETED, rc;
-+ struct scst_tgt_dev *tgt_dev_tmp;
-+ struct scst_device *dev;
-+
-+ TRACE_ENTRY();
-+
-+ dev = cmd->dev;
-+
-+ /*
-+ * See comment in scst_reserve_local() why no dev blocking or any
-+ * other protection is needed here.
-+ */
-+
-+ rc = scst_pre_check_local_events(cmd);
-+ if (unlikely(rc != 0))
-+ goto out_done;
-+
-+ if (!list_empty(&dev->dev_registrants_list)) {
-+ if (scst_pr_crh_case(cmd))
-+ goto out_completed;
-+ else {
-+ scst_set_cmd_error_status(cmd,
-+ SAM_STAT_RESERVATION_CONFLICT);
-+ goto out_done;
-+ }
-+ }
-+
-+ spin_lock_bh(&dev->dev_lock);
-+
-+ /*
-+ * The device could be RELEASED behind us, if RESERVING session
-+ * is closed (see scst_free_tgt_dev()), but this actually doesn't
-+ * matter, so use lock and no retest for DEV_RESERVED bits again
-+ */
-+ if (test_bit(SCST_TGT_DEV_RESERVED, &cmd->tgt_dev->tgt_dev_flags)) {
-+ res = SCST_EXEC_COMPLETED;
-+ cmd->status = 0;
-+ cmd->msg_status = 0;
-+ cmd->host_status = DID_OK;
-+ cmd->driver_status = 0;
-+ cmd->completed = 1;
-+ } else {
-+ list_for_each_entry(tgt_dev_tmp,
-+ &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ clear_bit(SCST_TGT_DEV_RESERVED,
-+ &tgt_dev_tmp->tgt_dev_flags);
-+ }
-+ dev->dev_reserved = 0;
-+ }
-+
-+ spin_unlock_bh(&dev->dev_lock);
-+
-+ if (res == SCST_EXEC_COMPLETED)
-+ goto out_done;
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_completed:
-+ cmd->completed = 1;
-+
-+out_done:
-+ res = SCST_EXEC_COMPLETED;
-+ /* Report the result */
-+ cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
-+ goto out;
-+}
-+
-+/* No locks, no IRQ or IRQ-disabled context allowed */
-+static int scst_persistent_reserve_in_local(struct scst_cmd *cmd)
-+{
-+ int rc;
-+ struct scst_device *dev;
-+ struct scst_tgt_dev *tgt_dev;
-+ struct scst_session *session;
-+ int action;
-+ uint8_t *buffer;
-+ int buffer_size;
-+
-+ TRACE_ENTRY();
-+
-+ EXTRACHECKS_BUG_ON(scst_cmd_atomic(cmd));
-+
-+ dev = cmd->dev;
-+ tgt_dev = cmd->tgt_dev;
-+ session = cmd->sess;
-+
-+ rc = scst_check_local_events(cmd);
-+ if (unlikely(rc != 0))
-+ goto out_done;
-+
-+ if (unlikely(dev->not_pr_supporting_tgt_devs_num != 0)) {
-+ PRINT_WARNING("Persistent Reservation command %x refused for "
-+ "device %s, because the device has not supporting PR "
-+ "transports connected", cmd->cdb[0], dev->virt_name);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_opcode));
-+ goto out_done;
-+ }
-+
-+ if (dev->dev_reserved) {
-+ TRACE_PR("PR command rejected, because device %s holds regular "
-+ "reservation", dev->virt_name);
-+ scst_set_cmd_error_status(cmd, SAM_STAT_RESERVATION_CONFLICT);
-+ goto out_done;
-+ }
-+
-+ if (dev->scsi_dev != NULL) {
-+ PRINT_WARNING("PR commands for pass-through devices not "
-+ "supported (device %s)", dev->virt_name);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_opcode));
-+ goto out_done;
-+ }
-+
-+ buffer_size = scst_get_buf_full(cmd, &buffer);
-+ if (unlikely(buffer_size <= 0)) {
-+ if (buffer_size < 0)
-+ scst_set_busy(cmd);
-+ goto out_done;
-+ }
-+
-+ scst_pr_write_lock(dev);
-+
-+ /* We can be aborted by another PR command while waiting for the lock */
-+ if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
-+ TRACE_MGMT_DBG("ABORTED set, aborting cmd %p", cmd);
-+ goto out_unlock;
-+ }
-+
-+ action = cmd->cdb[1] & 0x1f;
-+
-+ TRACE(TRACE_SCSI, "PR action %x for '%s' (LUN %llx) from '%s'", action,
-+ dev->virt_name, tgt_dev->lun, session->initiator_name);
-+
-+ switch (action) {
-+ case PR_READ_KEYS:
-+ scst_pr_read_keys(cmd, buffer, buffer_size);
-+ break;
-+ case PR_READ_RESERVATION:
-+ scst_pr_read_reservation(cmd, buffer, buffer_size);
-+ break;
-+ case PR_REPORT_CAPS:
-+ scst_pr_report_caps(cmd, buffer, buffer_size);
-+ break;
-+ case PR_READ_FULL_STATUS:
-+ scst_pr_read_full_status(cmd, buffer, buffer_size);
-+ break;
-+ default:
-+ PRINT_ERROR("Unsupported action %x", action);
-+ scst_pr_write_unlock(dev);
-+ goto out_err;
-+ }
-+
-+out_complete:
-+ cmd->completed = 1;
-+
-+out_unlock:
-+ scst_pr_write_unlock(dev);
-+
-+ scst_put_buf_full(cmd, buffer);
-+
-+out_done:
-+ cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
-+
-+ TRACE_EXIT_RES(SCST_EXEC_COMPLETED);
-+ return SCST_EXEC_COMPLETED;
-+
-+out_err:
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
-+ goto out_complete;
-+}
-+
-+/* No locks, no IRQ or IRQ-disabled context allowed */
-+static int scst_persistent_reserve_out_local(struct scst_cmd *cmd)
-+{
-+ int res = SCST_EXEC_COMPLETED;
-+ int rc;
-+ struct scst_device *dev;
-+ struct scst_tgt_dev *tgt_dev;
-+ struct scst_session *session;
-+ int action;
-+ uint8_t *buffer;
-+ int buffer_size;
-+ bool aborted = false;
-+
-+ TRACE_ENTRY();
-+
-+ EXTRACHECKS_BUG_ON(scst_cmd_atomic(cmd));
-+
-+ dev = cmd->dev;
-+ tgt_dev = cmd->tgt_dev;
-+ session = cmd->sess;
-+
-+ rc = scst_check_local_events(cmd);
-+ if (unlikely(rc != 0))
-+ goto out_done;
-+
-+ if (unlikely(dev->not_pr_supporting_tgt_devs_num != 0)) {
-+ PRINT_WARNING("Persistent Reservation command %x refused for "
-+ "device %s, because the device has not supporting PR "
-+ "transports connected", cmd->cdb[0], dev->virt_name);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_opcode));
-+ goto out_done;
-+ }
-+
-+ action = cmd->cdb[1] & 0x1f;
-+
-+ TRACE(TRACE_SCSI, "PR action %x for '%s' (LUN %llx) from '%s'", action,
-+ dev->virt_name, tgt_dev->lun, session->initiator_name);
-+
-+ if (dev->dev_reserved) {
-+ TRACE_PR("PR command rejected, because device %s holds regular "
-+ "reservation", dev->virt_name);
-+ scst_set_cmd_error_status(cmd, SAM_STAT_RESERVATION_CONFLICT);
-+ goto out_done;
-+ }
-+
-+ /*
-+ * Check if tgt_dev already registered. Also by this check we make
-+ * sure that table "PERSISTENT RESERVE OUT service actions that are
-+ * allowed in the presence of various reservations" is honored.
-+ * REGISTER AND MOVE and RESERVE will be additionally checked for
-+ * conflicts later.
-+ */
-+ if ((action != PR_REGISTER) && (action != PR_REGISTER_AND_IGNORE) &&
-+ (tgt_dev->registrant == NULL)) {
-+ TRACE_PR("'%s' not registered", cmd->sess->initiator_name);
-+ scst_set_cmd_error_status(cmd, SAM_STAT_RESERVATION_CONFLICT);
-+ goto out_done;
-+ }
-+
-+ buffer_size = scst_get_buf_full(cmd, &buffer);
-+ if (unlikely(buffer_size <= 0)) {
-+ if (buffer_size < 0)
-+ scst_set_busy(cmd);
-+ goto out_done;
-+ }
-+
-+ /* Check scope */
-+ if ((action != PR_REGISTER) && (action != PR_REGISTER_AND_IGNORE) &&
-+ (action != PR_CLEAR) && ((cmd->cdb[2] & 0x0f) >> 4) != SCOPE_LU) {
-+ TRACE_PR("Scope must be SCOPE_LU for action %x", action);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
-+ goto out_put_buf_full;
-+ }
-+
-+ /* Check SPEC_I_PT (PR_REGISTER_AND_MOVE has another format) */
-+ if ((action != PR_REGISTER) && (action != PR_REGISTER_AND_MOVE) &&
-+ ((buffer[20] >> 3) & 0x01)) {
-+ TRACE_PR("SPEC_I_PT must be zero for action %x", action);
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
-+ scst_sense_invalid_field_in_cdb));
-+ goto out_put_buf_full;
-+ }
-+
-+ /* Check ALL_TG_PT (PR_REGISTER_AND_MOVE has another format) */
-+ if ((action != PR_REGISTER) && (action != PR_REGISTER_AND_IGNORE) &&
-+ (action != PR_REGISTER_AND_MOVE) && ((buffer[20] >> 2) & 0x01)) {
-+ TRACE_PR("ALL_TG_PT must be zero for action %x", action);
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
-+ scst_sense_invalid_field_in_cdb));
-+ goto out_put_buf_full;
-+ }
-+
-+ scst_pr_write_lock(dev);
-+
-+ /* We can be aborted by another PR command while waiting for the lock */
-+ aborted = test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags);
-+ if (unlikely(aborted)) {
-+ TRACE_MGMT_DBG("ABORTED set, aborting cmd %p", cmd);
-+ goto out_unlock;
-+ }
-+
-+ switch (action) {
-+ case PR_REGISTER:
-+ scst_pr_register(cmd, buffer, buffer_size);
-+ break;
-+ case PR_RESERVE:
-+ scst_pr_reserve(cmd, buffer, buffer_size);
-+ break;
-+ case PR_RELEASE:
-+ scst_pr_release(cmd, buffer, buffer_size);
-+ break;
-+ case PR_CLEAR:
-+ scst_pr_clear(cmd, buffer, buffer_size);
-+ break;
-+ case PR_PREEMPT:
-+ scst_pr_preempt(cmd, buffer, buffer_size);
-+ break;
-+ case PR_PREEMPT_AND_ABORT:
-+ scst_pr_preempt_and_abort(cmd, buffer, buffer_size);
-+ break;
-+ case PR_REGISTER_AND_IGNORE:
-+ scst_pr_register_and_ignore(cmd, buffer, buffer_size);
-+ break;
-+ case PR_REGISTER_AND_MOVE:
-+ scst_pr_register_and_move(cmd, buffer, buffer_size);
-+ break;
-+ default:
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
-+ goto out_unlock;
-+ }
-+
-+ if (cmd->status == SAM_STAT_GOOD)
-+ scst_pr_sync_device_file(tgt_dev, cmd);
-+
-+ if ((dev->handler->pr_cmds_notifications) &&
-+ (cmd->status == SAM_STAT_GOOD)) /* sync file may change status */
-+ res = SCST_EXEC_NOT_COMPLETED;
-+
-+out_unlock:
-+ scst_pr_write_unlock(dev);
-+
-+out_put_buf_full:
-+ scst_put_buf_full(cmd, buffer);
-+
-+out_done:
-+ if (SCST_EXEC_COMPLETED == res) {
-+ if (!aborted)
-+ cmd->completed = 1;
-+ cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
-+ SCST_CONTEXT_SAME);
-+ }
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/**
-+ * scst_check_local_events() - check if there are any local SCSI events
-+ *
-+ * Description:
-+ * Checks if the command can be executed or there are local events,
-+ * like reservations, pending UAs, etc. Returns < 0 if command must be
-+ * aborted, > 0 if there is an event and command should be immediately
-+ * completed, or 0 otherwise.
-+ *
-+ * !! 1.Dev handlers implementing exec() callback must call this function there
-+ * !! just before the actual command's execution!
-+ * !!
-+ * !! 2. If this function can be called more than once on the processing path
-+ * !! scst_pre_check_local_events() should be used for the first call!
-+ *
-+ * On call no locks, no IRQ or IRQ-disabled context allowed.
-+ */
-+int scst_check_local_events(struct scst_cmd *cmd)
-+{
-+ int res, rc;
-+ struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
-+ struct scst_device *dev = cmd->dev;
-+
-+ TRACE_ENTRY();
-+
-+ /*
-+ * There's no race here, because we need to trace commands sent
-+ * *after* dev_double_ua_possible flag was set.
-+ */
-+ if (unlikely(dev->dev_double_ua_possible))
-+ cmd->double_ua_possible = 1;
-+
-+ /* Reserve check before Unit Attention */
-+ if (unlikely(test_bit(SCST_TGT_DEV_RESERVED,
-+ &tgt_dev->tgt_dev_flags))) {
-+ if ((cmd->op_flags & SCST_REG_RESERVE_ALLOWED) == 0) {
-+ scst_set_cmd_error_status(cmd,
-+ SAM_STAT_RESERVATION_CONFLICT);
-+ goto out_dec_pr_readers_count;
-+ }
-+ }
-+
-+ if (likely(!cmd->check_local_events_once_done)) {
-+ if (dev->pr_is_set) {
-+ if (unlikely(!scst_pr_is_cmd_allowed(cmd))) {
-+ scst_set_cmd_error_status(cmd,
-+ SAM_STAT_RESERVATION_CONFLICT);
-+ goto out_complete;
-+ }
-+ } else
-+ scst_dec_pr_readers_count(cmd, false);
-+ }
-+
-+ /*
-+ * Let's check for ABORTED after scst_pr_is_cmd_allowed(), because
-+ * we might sleep for a while there.
-+ */
-+ if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
-+ TRACE_MGMT_DBG("ABORTED set, aborting cmd %p", cmd);
-+ goto out_uncomplete;
-+ }
-+
-+ /* If we had internal bus reset, set the command error unit attention */
-+ if ((dev->scsi_dev != NULL) &&
-+ unlikely(dev->scsi_dev->was_reset)) {
-+ if (scst_is_ua_command(cmd)) {
-+ int done = 0;
-+ /*
-+ * Prevent more than 1 cmd to be triggered by was_reset
-+ */
-+ spin_lock_bh(&dev->dev_lock);
-+ if (dev->scsi_dev->was_reset) {
-+ TRACE(TRACE_MGMT, "was_reset is %d", 1);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_reset_UA));
-+ /*
-+ * It looks like it is safe to clear was_reset
-+ * here
-+ */
-+ dev->scsi_dev->was_reset = 0;
-+ done = 1;
-+ }
-+ spin_unlock_bh(&dev->dev_lock);
-+
-+ if (done)
-+ goto out_complete;
-+ }
-+ }
-+
-+ if (unlikely(test_bit(SCST_TGT_DEV_UA_PENDING,
-+ &cmd->tgt_dev->tgt_dev_flags))) {
-+ if (scst_is_ua_command(cmd)) {
-+ rc = scst_set_pending_UA(cmd);
-+ if (rc == 0)
-+ goto out_complete;
-+ }
-+ }
-+
-+ res = 0;
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_dec_pr_readers_count:
-+ if (cmd->dec_pr_readers_count_needed)
-+ scst_dec_pr_readers_count(cmd, false);
-+
-+out_complete:
-+ res = 1;
-+ BUG_ON(!cmd->completed);
-+ goto out;
-+
-+out_uncomplete:
-+ res = -1;
-+ goto out;
-+}
-+EXPORT_SYMBOL_GPL(scst_check_local_events);
-+
-+/* No locks */
-+void scst_inc_expected_sn(struct scst_order_data *order_data, atomic_t *slot)
-+{
-+ if (slot == NULL)
-+ goto inc;
-+
-+ /* Optimized for lockless fast path */
-+
-+ TRACE_SN("Slot %zd, *cur_sn_slot %d", slot - order_data->sn_slots,
-+ atomic_read(slot));
-+
-+ if (!atomic_dec_and_test(slot))
-+ goto out;
-+
-+ TRACE_SN("Slot is 0 (num_free_sn_slots=%d)",
-+ order_data->num_free_sn_slots);
-+ if (order_data->num_free_sn_slots < (int)ARRAY_SIZE(order_data->sn_slots)-1) {
-+ spin_lock_irq(&order_data->sn_lock);
-+ if (likely(order_data->num_free_sn_slots < (int)ARRAY_SIZE(order_data->sn_slots)-1)) {
-+ if (order_data->num_free_sn_slots < 0)
-+ order_data->cur_sn_slot = slot;
-+ /* To be in-sync with SIMPLE case in scst_cmd_set_sn() */
-+ smp_mb();
-+ order_data->num_free_sn_slots++;
-+ TRACE_SN("Incremented num_free_sn_slots (%d)",
-+ order_data->num_free_sn_slots);
-+
-+ }
-+ spin_unlock_irq(&order_data->sn_lock);
-+ }
-+
-+inc:
-+ /*
-+ * No protection of expected_sn is needed, because only one thread
-+ * at time can be here (serialized by sn). Also it is supposed that
-+ * there could not be half-incremented halves.
-+ */
-+ order_data->expected_sn++;
-+ /*
-+ * Write must be before def_cmd_count read to be in sync. with
-+ * scst_post_exec_sn(). See comment in scst_send_for_exec().
-+ */
-+ smp_mb();
-+ TRACE_SN("Next expected_sn: %d", order_data->expected_sn);
-+
-+out:
-+ return;
-+}
-+
-+/* No locks */
-+static struct scst_cmd *scst_post_exec_sn(struct scst_cmd *cmd,
-+ bool make_active)
-+{
-+ /* For HQ commands SN is not set */
-+ bool inc_expected_sn = !cmd->inc_expected_sn_on_done &&
-+ cmd->sn_set && !cmd->retry;
-+ struct scst_order_data *order_data = cmd->cur_order_data;
-+ struct scst_cmd *res;
-+
-+ TRACE_ENTRY();
-+
-+ if (inc_expected_sn)
-+ scst_inc_expected_sn(order_data, cmd->sn_slot);
-+
-+ if (make_active) {
-+ scst_make_deferred_commands_active(order_data);
-+ res = NULL;
-+ } else
-+ res = scst_check_deferred_commands(order_data);
-+
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+/* cmd must be additionally referenced to not die inside */
-+static int scst_do_real_exec(struct scst_cmd *cmd)
-+{
-+ int res = SCST_EXEC_NOT_COMPLETED;
-+ int rc;
-+ struct scst_device *dev = cmd->dev;
-+ struct scst_dev_type *handler = dev->handler;
-+ struct io_context *old_ctx = NULL;
-+ bool ctx_changed = false;
-+ struct scsi_device *scsi_dev;
-+
-+ TRACE_ENTRY();
-+
-+ ctx_changed = scst_set_io_context(cmd, &old_ctx);
-+
-+ cmd->state = SCST_CMD_STATE_REAL_EXECUTING;
-+
-+ if (handler->exec) {
-+ TRACE_DBG("Calling dev handler %s exec(%p)",
-+ handler->name, cmd);
-+ TRACE_BUFF_FLAG(TRACE_SND_TOP, "Execing: ", cmd->cdb,
-+ cmd->cdb_len);
-+ scst_set_cur_start(cmd);
-+ res = handler->exec(cmd);
-+ TRACE_DBG("Dev handler %s exec() returned %d",
-+ handler->name, res);
-+
-+ if (res == SCST_EXEC_COMPLETED)
-+ goto out_complete;
-+
-+ scst_set_exec_time(cmd);
-+
-+ BUG_ON(res != SCST_EXEC_NOT_COMPLETED);
-+ }
-+
-+ TRACE_DBG("Sending cmd %p to SCSI mid-level", cmd);
-+
-+ scsi_dev = dev->scsi_dev;
-+
-+ if (unlikely(scsi_dev == NULL)) {
-+ PRINT_ERROR("Command for virtual device must be "
-+ "processed by device handler (LUN %lld)!",
-+ (long long unsigned int)cmd->lun);
-+ goto out_error;
-+ }
-+
-+ res = scst_check_local_events(cmd);
-+ if (unlikely(res != 0))
-+ goto out_done;
-+
-+ scst_set_cur_start(cmd);
-+
-+ rc = scst_scsi_exec_async(cmd, cmd, scst_pass_through_cmd_done);
-+ if (unlikely(rc != 0)) {
-+ PRINT_ERROR("scst pass-through exec failed: %x", rc);
-+ if (((int)rc == -EINVAL) &&
-+ (cmd->bufflen > queue_max_hw_sectors(scsi_dev->request_queue)))
-+ PRINT_ERROR("Too low max_hw_sectors %d sectors on %s "
-+ "to serve command %x with bufflen %db."
-+ "See README for more details.",
-+ queue_max_hw_sectors(scsi_dev->request_queue),
-+ dev->virt_name, cmd->cdb[0], cmd->bufflen);
-+ goto out_error;
-+ }
-+
-+out_complete:
-+ res = SCST_EXEC_COMPLETED;
-+
-+ if (ctx_changed)
-+ scst_reset_io_context(cmd->tgt_dev, old_ctx);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_error:
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ goto out_done;
-+
-+out_done:
-+ res = SCST_EXEC_COMPLETED;
-+ /* Report the result */
-+ cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
-+ goto out_complete;
-+}
-+
-+static inline int scst_real_exec(struct scst_cmd *cmd)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ BUILD_BUG_ON(SCST_CMD_STATE_RES_CONT_SAME != SCST_EXEC_NOT_COMPLETED);
-+ BUILD_BUG_ON(SCST_CMD_STATE_RES_CONT_NEXT != SCST_EXEC_COMPLETED);
-+
-+ __scst_cmd_get(cmd);
-+
-+ res = scst_do_real_exec(cmd);
-+ if (likely(res == SCST_EXEC_COMPLETED)) {
-+ scst_post_exec_sn(cmd, true);
-+ } else
-+ BUG();
-+
-+ __scst_cmd_put(cmd);
-+
-+ /* SCST_EXEC_* match SCST_CMD_STATE_RES_* */
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static int scst_do_local_exec(struct scst_cmd *cmd)
-+{
-+ int res;
-+ struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
-+
-+ TRACE_ENTRY();
-+
-+ /* Check READ_ONLY device status */
-+ if ((cmd->op_flags & SCST_WRITE_MEDIUM) &&
-+ (tgt_dev->acg_dev->rd_only || cmd->dev->swp ||
-+ cmd->dev->rd_only)) {
-+ PRINT_WARNING("Attempt of write access to read-only device: "
-+ "initiator %s, LUN %lld, op %x",
-+ cmd->sess->initiator_name, cmd->lun, cmd->cdb[0]);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_data_protect));
-+ goto out_done;
-+ }
-+
-+ if (!scst_is_cmd_local(cmd)) {
-+ res = SCST_EXEC_NOT_COMPLETED;
-+ goto out;
-+ }
-+
-+ switch (cmd->cdb[0]) {
-+ case RESERVE:
-+ case RESERVE_10:
-+ res = scst_reserve_local(cmd);
-+ break;
-+ case RELEASE:
-+ case RELEASE_10:
-+ res = scst_release_local(cmd);
-+ break;
-+ case PERSISTENT_RESERVE_IN:
-+ res = scst_persistent_reserve_in_local(cmd);
-+ break;
-+ case PERSISTENT_RESERVE_OUT:
-+ res = scst_persistent_reserve_out_local(cmd);
-+ break;
-+ case REPORT_LUNS:
-+ res = scst_report_luns_local(cmd);
-+ break;
-+ case REQUEST_SENSE:
-+ res = scst_request_sense_local(cmd);
-+ break;
-+ default:
-+ res = SCST_EXEC_NOT_COMPLETED;
-+ break;
-+ }
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_done:
-+ /* Report the result */
-+ cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
-+ res = SCST_EXEC_COMPLETED;
-+ goto out;
-+}
-+
-+static int scst_local_exec(struct scst_cmd *cmd)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ BUILD_BUG_ON(SCST_CMD_STATE_RES_CONT_SAME != SCST_EXEC_NOT_COMPLETED);
-+ BUILD_BUG_ON(SCST_CMD_STATE_RES_CONT_NEXT != SCST_EXEC_COMPLETED);
-+
-+ __scst_cmd_get(cmd);
-+
-+ res = scst_do_local_exec(cmd);
-+ if (likely(res == SCST_EXEC_NOT_COMPLETED))
-+ cmd->state = SCST_CMD_STATE_REAL_EXEC;
-+ else if (res == SCST_EXEC_COMPLETED)
-+ scst_post_exec_sn(cmd, true);
-+ else
-+ BUG();
-+
-+ __scst_cmd_put(cmd);
-+
-+ /* SCST_EXEC_* match SCST_CMD_STATE_RES_* */
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static int scst_exec(struct scst_cmd **active_cmd)
-+{
-+ struct scst_cmd *cmd = *active_cmd;
-+ struct scst_cmd *ref_cmd;
-+ int res = SCST_CMD_STATE_RES_CONT_NEXT, count = 0;
-+
-+ TRACE_ENTRY();
-+
-+ cmd->state = SCST_CMD_STATE_START_EXEC;
-+
-+ if (unlikely(scst_check_blocked_dev(cmd)))
-+ goto out;
-+
-+ /* To protect tgt_dev */
-+ ref_cmd = cmd;
-+ __scst_cmd_get(ref_cmd);
-+
-+ while (1) {
-+ int rc;
-+
-+ cmd->sent_for_exec = 1;
-+ /*
-+ * To sync with scst_abort_cmd(). The above assignment must
-+ * be before SCST_CMD_ABORTED test, done later in
-+ * scst_check_local_events(). It's far from here, so the order
-+ * is virtually guaranteed, but let's have it just in case.
-+ */
-+ smp_mb();
-+
-+ cmd->scst_cmd_done = scst_cmd_done_local;
-+ cmd->state = SCST_CMD_STATE_LOCAL_EXEC;
-+
-+ rc = scst_do_local_exec(cmd);
-+ if (likely(rc == SCST_EXEC_NOT_COMPLETED))
-+ /* Nothing to do */;
-+ else {
-+ BUG_ON(rc != SCST_EXEC_COMPLETED);
-+ goto done;
-+ }
-+
-+ cmd->state = SCST_CMD_STATE_REAL_EXEC;
-+
-+ rc = scst_do_real_exec(cmd);
-+ BUG_ON(rc != SCST_EXEC_COMPLETED);
-+
-+done:
-+ count++;
-+
-+ cmd = scst_post_exec_sn(cmd, false);
-+ if (cmd == NULL)
-+ break;
-+
-+ cmd->state = SCST_CMD_STATE_START_EXEC;
-+
-+ if (unlikely(scst_check_blocked_dev(cmd)))
-+ break;
-+
-+ __scst_cmd_put(ref_cmd);
-+ ref_cmd = cmd;
-+ __scst_cmd_get(ref_cmd);
-+
-+ }
-+
-+ *active_cmd = cmd;
-+
-+ if (count == 0)
-+ goto out_put;
-+
-+out_put:
-+ __scst_cmd_put(ref_cmd);
-+ /* !! At this point sess, dev and tgt_dev can be already freed !! */
-+
-+out:
-+ EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD);
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static int scst_send_for_exec(struct scst_cmd **active_cmd)
-+{
-+ int res;
-+ struct scst_cmd *cmd = *active_cmd;
-+ struct scst_order_data *order_data = cmd->cur_order_data;
-+ typeof(order_data->expected_sn) expected_sn;
-+
-+ TRACE_ENTRY();
-+
-+ if (unlikely(cmd->internal))
-+ goto exec;
-+
-+ if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
-+ goto exec;
-+
-+ BUG_ON(!cmd->sn_set);
-+
-+ expected_sn = order_data->expected_sn;
-+ /* Optimized for lockless fast path */
-+ if ((cmd->sn != expected_sn) || (order_data->hq_cmd_count > 0)) {
-+ spin_lock_irq(&order_data->sn_lock);
-+
-+ order_data->def_cmd_count++;
-+ /*
-+ * Memory barrier is needed here to implement lockless fast
-+ * path. We need the exact order of read and write between
-+ * def_cmd_count and expected_sn. Otherwise, we can miss case,
-+ * when expected_sn was changed to be equal to cmd->sn while
-+ * we are queueing cmd the deferred list after the expected_sn
-+ * below. It will lead to a forever stuck command. But with
-+ * the barrier in such case __scst_check_deferred_commands()
-+ * will be called and it will take sn_lock, so we will be
-+ * synchronized.
-+ */
-+ smp_mb();
-+
-+ expected_sn = order_data->expected_sn;
-+ if ((cmd->sn != expected_sn) || (order_data->hq_cmd_count > 0)) {
-+ if (unlikely(test_bit(SCST_CMD_ABORTED,
-+ &cmd->cmd_flags))) {
-+ /* Necessary to allow aborting out of sn cmds */
-+ TRACE_MGMT_DBG("Aborting out of sn cmd %p "
-+ "(tag %llu, sn %u)", cmd,
-+ (long long unsigned)cmd->tag, cmd->sn);
-+ order_data->def_cmd_count--;
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+ } else {
-+ TRACE_SN("Deferring cmd %p (sn=%d, set %d, "
-+ "expected_sn=%d)", cmd, cmd->sn,
-+ cmd->sn_set, expected_sn);
-+ list_add_tail(&cmd->sn_cmd_list_entry,
-+ &order_data->deferred_cmd_list);
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+ }
-+ spin_unlock_irq(&order_data->sn_lock);
-+ goto out;
-+ } else {
-+ TRACE_SN("Somebody incremented expected_sn %d, "
-+ "continuing", expected_sn);
-+ order_data->def_cmd_count--;
-+ spin_unlock_irq(&order_data->sn_lock);
-+ }
-+ }
-+
-+exec:
-+ res = scst_exec(active_cmd);
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+/* No locks supposed to be held */
-+static int scst_check_sense(struct scst_cmd *cmd)
-+{
-+ int res = 0;
-+ struct scst_device *dev = cmd->dev;
-+
-+ TRACE_ENTRY();
-+
-+ if (unlikely(cmd->ua_ignore))
-+ goto out;
-+
-+ /* If we had internal bus reset behind us, set the command error UA */
-+ if ((dev->scsi_dev != NULL) &&
-+ unlikely(cmd->host_status == DID_RESET) &&
-+ scst_is_ua_command(cmd)) {
-+ TRACE(TRACE_MGMT, "DID_RESET: was_reset=%d host_status=%x",
-+ dev->scsi_dev->was_reset, cmd->host_status);
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_reset_UA));
-+ /* It looks like it is safe to clear was_reset here */
-+ dev->scsi_dev->was_reset = 0;
-+ }
-+
-+ if (unlikely(cmd->status == SAM_STAT_CHECK_CONDITION) &&
-+ SCST_SENSE_VALID(cmd->sense)) {
-+ PRINT_BUFF_FLAG(TRACE_SCSI, "Sense", cmd->sense,
-+ cmd->sense_valid_len);
-+
-+ /* Check Unit Attention Sense Key */
-+ if (scst_is_ua_sense(cmd->sense, cmd->sense_valid_len)) {
-+ if (scst_analyze_sense(cmd->sense, cmd->sense_valid_len,
-+ SCST_SENSE_ASC_VALID,
-+ 0, SCST_SENSE_ASC_UA_RESET, 0)) {
-+ if (cmd->double_ua_possible) {
-+ TRACE_MGMT_DBG("Double UA "
-+ "detected for device %p", dev);
-+ TRACE_MGMT_DBG("Retrying cmd"
-+ " %p (tag %llu)", cmd,
-+ (long long unsigned)cmd->tag);
-+
-+ cmd->status = 0;
-+ cmd->msg_status = 0;
-+ cmd->host_status = DID_OK;
-+ cmd->driver_status = 0;
-+ cmd->completed = 0;
-+
-+ mempool_free(cmd->sense,
-+ scst_sense_mempool);
-+ cmd->sense = NULL;
-+
-+ scst_check_restore_sg_buff(cmd);
-+
-+ BUG_ON(cmd->dbl_ua_orig_resp_data_len < 0);
-+ cmd->data_direction =
-+ cmd->dbl_ua_orig_data_direction;
-+ cmd->resp_data_len =
-+ cmd->dbl_ua_orig_resp_data_len;
-+
-+ cmd->state = SCST_CMD_STATE_REAL_EXEC;
-+ cmd->retry = 1;
-+ scst_reset_requeued_cmd(cmd);
-+ res = 1;
-+ goto out;
-+ }
-+ }
-+ scst_dev_check_set_UA(dev, cmd, cmd->sense,
-+ cmd->sense_valid_len);
-+ }
-+ }
-+
-+ if (unlikely(cmd->double_ua_possible)) {
-+ if (scst_is_ua_command(cmd)) {
-+ TRACE_MGMT_DBG("Clearing dbl_ua_possible flag (dev %p, "
-+ "cmd %p)", dev, cmd);
-+ /*
-+ * Lock used to protect other flags in the bitfield
-+ * (just in case, actually). Those flags can't be
-+ * changed in parallel, because the device is
-+ * serialized.
-+ */
-+ spin_lock_bh(&dev->dev_lock);
-+ dev->dev_double_ua_possible = 0;
-+ spin_unlock_bh(&dev->dev_lock);
-+ }
-+ }
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static int scst_check_auto_sense(struct scst_cmd *cmd)
-+{
-+ int res = 0;
-+
-+ TRACE_ENTRY();
-+
-+ if (unlikely(cmd->status == SAM_STAT_CHECK_CONDITION) &&
-+ (!SCST_SENSE_VALID(cmd->sense) ||
-+ SCST_NO_SENSE(cmd->sense))) {
-+ TRACE(TRACE_SCSI|TRACE_MINOR_AND_MGMT_DBG, "CHECK_CONDITION, "
-+ "but no sense: cmd->status=%x, cmd->msg_status=%x, "
-+ "cmd->host_status=%x, cmd->driver_status=%x (cmd %p)",
-+ cmd->status, cmd->msg_status, cmd->host_status,
-+ cmd->driver_status, cmd);
-+ res = 1;
-+ } else if (unlikely(cmd->host_status)) {
-+ if ((cmd->host_status == DID_REQUEUE) ||
-+ (cmd->host_status == DID_IMM_RETRY) ||
-+ (cmd->host_status == DID_SOFT_ERROR) ||
-+ (cmd->host_status == DID_ABORT)) {
-+ scst_set_busy(cmd);
-+ } else {
-+ TRACE(TRACE_SCSI|TRACE_MINOR_AND_MGMT_DBG, "Host "
-+ "status %x received, returning HARDWARE ERROR "
-+ "instead (cmd %p)", cmd->host_status, cmd);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ }
-+ }
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static int scst_pre_dev_done(struct scst_cmd *cmd)
-+{
-+ int res = SCST_CMD_STATE_RES_CONT_SAME, rc;
-+
-+ TRACE_ENTRY();
-+
-+ if (unlikely(scst_check_auto_sense(cmd))) {
-+ PRINT_INFO("Command finished with CHECK CONDITION, but "
-+ "without sense data (opcode 0x%x), issuing "
-+ "REQUEST SENSE", cmd->cdb[0]);
-+ rc = scst_prepare_request_sense(cmd);
-+ if (rc == 0)
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+ else {
-+ PRINT_ERROR("%s", "Unable to issue REQUEST SENSE, "
-+ "returning HARDWARE ERROR");
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ }
-+ goto out;
-+ } else if (unlikely(scst_check_sense(cmd))) {
-+ /*
-+ * We can't allow atomic command on the exec stages, so
-+ * restart to the thread
-+ */
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+
-+ if (likely(scsi_status_is_good(cmd->status))) {
-+ unsigned char type = cmd->dev->type;
-+ if (unlikely((cmd->cdb[0] == MODE_SENSE ||
-+ cmd->cdb[0] == MODE_SENSE_10)) &&
-+ (cmd->tgt_dev->acg_dev->rd_only || cmd->dev->swp ||
-+ cmd->dev->rd_only) &&
-+ (type == TYPE_DISK ||
-+ type == TYPE_WORM ||
-+ type == TYPE_MOD ||
-+ type == TYPE_TAPE)) {
-+ int32_t length;
-+ uint8_t *address;
-+ bool err = false;
-+
-+ length = scst_get_buf_full(cmd, &address);
-+ if (length < 0) {
-+ PRINT_ERROR("%s", "Unable to get "
-+ "MODE_SENSE buffer");
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(
-+ scst_sense_hardw_error));
-+ err = true;
-+ } else if (length > 2 && cmd->cdb[0] == MODE_SENSE)
-+ address[2] |= 0x80; /* Write Protect*/
-+ else if (length > 3 && cmd->cdb[0] == MODE_SENSE_10)
-+ address[3] |= 0x80; /* Write Protect*/
-+ scst_put_buf_full(cmd, address);
-+
-+ if (err)
-+ goto out;
-+ }
-+
-+ /*
-+ * Check and clear NormACA option for the device, if necessary,
-+ * since we don't support ACA
-+ */
-+ if (unlikely((cmd->cdb[0] == INQUIRY)) &&
-+ /* Std INQUIRY data (no EVPD) */
-+ !(cmd->cdb[1] & SCST_INQ_EVPD) &&
-+ (cmd->resp_data_len > SCST_INQ_BYTE3)) {
-+ uint8_t *buffer;
-+ int buflen;
-+ bool err = false;
-+
-+ buflen = scst_get_buf_full(cmd, &buffer);
-+ if (buflen > SCST_INQ_BYTE3 && !cmd->tgtt->fake_aca) {
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ if (buffer[SCST_INQ_BYTE3] & SCST_INQ_NORMACA_BIT) {
-+ PRINT_INFO("NormACA set for device: "
-+ "lun=%lld, type 0x%02x. Clear it, "
-+ "since it's unsupported.",
-+ (long long unsigned int)cmd->lun,
-+ buffer[0]);
-+ }
-+#endif
-+ buffer[SCST_INQ_BYTE3] &= ~SCST_INQ_NORMACA_BIT;
-+ } else if (buflen <= SCST_INQ_BYTE3 && buflen != 0) {
-+ PRINT_ERROR("%s", "Unable to get INQUIRY "
-+ "buffer");
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ err = true;
-+ }
-+ if (buflen > 0)
-+ scst_put_buf_full(cmd, buffer);
-+
-+ if (err)
-+ goto out;
-+ }
-+
-+ if (unlikely((cmd->cdb[0] == MODE_SELECT) ||
-+ (cmd->cdb[0] == MODE_SELECT_10) ||
-+ (cmd->cdb[0] == LOG_SELECT))) {
-+ TRACE(TRACE_SCSI,
-+ "MODE/LOG SELECT succeeded (LUN %lld)",
-+ (long long unsigned int)cmd->lun);
-+ cmd->state = SCST_CMD_STATE_MODE_SELECT_CHECKS;
-+ goto out;
-+ }
-+ } else {
-+ TRACE(TRACE_SCSI, "cmd %p not succeeded with status %x",
-+ cmd, cmd->status);
-+
-+ if ((cmd->cdb[0] == RESERVE) || (cmd->cdb[0] == RESERVE_10)) {
-+ if (!test_bit(SCST_TGT_DEV_RESERVED,
-+ &cmd->tgt_dev->tgt_dev_flags)) {
-+ struct scst_tgt_dev *tgt_dev_tmp;
-+ struct scst_device *dev = cmd->dev;
-+
-+ TRACE(TRACE_SCSI, "RESERVE failed lun=%lld, "
-+ "status=%x",
-+ (long long unsigned int)cmd->lun,
-+ cmd->status);
-+ PRINT_BUFF_FLAG(TRACE_SCSI, "Sense", cmd->sense,
-+ cmd->sense_valid_len);
-+
-+ /* Clearing the reservation */
-+ spin_lock_bh(&dev->dev_lock);
-+ list_for_each_entry(tgt_dev_tmp,
-+ &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ clear_bit(SCST_TGT_DEV_RESERVED,
-+ &tgt_dev_tmp->tgt_dev_flags);
-+ }
-+ dev->dev_reserved = 0;
-+ spin_unlock_bh(&dev->dev_lock);
-+ }
-+ }
-+
-+ /* Check for MODE PARAMETERS CHANGED UA */
-+ if ((cmd->dev->scsi_dev != NULL) &&
-+ (cmd->status == SAM_STAT_CHECK_CONDITION) &&
-+ scst_is_ua_sense(cmd->sense, cmd->sense_valid_len) &&
-+ scst_analyze_sense(cmd->sense, cmd->sense_valid_len,
-+ SCST_SENSE_ASCx_VALID,
-+ 0, 0x2a, 0x01)) {
-+ TRACE(TRACE_SCSI, "MODE PARAMETERS CHANGED UA (lun "
-+ "%lld)", (long long unsigned int)cmd->lun);
-+ cmd->state = SCST_CMD_STATE_MODE_SELECT_CHECKS;
-+ goto out;
-+ }
-+ }
-+
-+ cmd->state = SCST_CMD_STATE_DEV_DONE;
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static int scst_mode_select_checks(struct scst_cmd *cmd)
-+{
-+ int res = SCST_CMD_STATE_RES_CONT_SAME;
-+
-+ TRACE_ENTRY();
-+
-+ if (likely(scsi_status_is_good(cmd->status))) {
-+ int atomic = scst_cmd_atomic(cmd);
-+ if (unlikely((cmd->cdb[0] == MODE_SELECT) ||
-+ (cmd->cdb[0] == MODE_SELECT_10) ||
-+ (cmd->cdb[0] == LOG_SELECT))) {
-+ struct scst_device *dev = cmd->dev;
-+ int sl;
-+ uint8_t sense_buffer[SCST_STANDARD_SENSE_LEN];
-+
-+ if (atomic && (dev->scsi_dev != NULL)) {
-+ TRACE_DBG("%s", "MODE/LOG SELECT: thread "
-+ "context required");
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+
-+ TRACE(TRACE_SCSI, "MODE/LOG SELECT succeeded, "
-+ "setting the SELECT UA (lun=%lld)",
-+ (long long unsigned int)cmd->lun);
-+
-+ spin_lock_bh(&dev->dev_lock);
-+ if (cmd->cdb[0] == LOG_SELECT) {
-+ sl = scst_set_sense(sense_buffer,
-+ sizeof(sense_buffer),
-+ dev->d_sense,
-+ UNIT_ATTENTION, 0x2a, 0x02);
-+ } else {
-+ sl = scst_set_sense(sense_buffer,
-+ sizeof(sense_buffer),
-+ dev->d_sense,
-+ UNIT_ATTENTION, 0x2a, 0x01);
-+ }
-+ scst_dev_check_set_local_UA(dev, cmd, sense_buffer, sl);
-+ spin_unlock_bh(&dev->dev_lock);
-+
-+ if (dev->scsi_dev != NULL)
-+ scst_obtain_device_parameters(dev);
-+ }
-+ } else if ((cmd->status == SAM_STAT_CHECK_CONDITION) &&
-+ scst_is_ua_sense(cmd->sense, cmd->sense_valid_len) &&
-+ /* mode parameters changed */
-+ (scst_analyze_sense(cmd->sense, cmd->sense_valid_len,
-+ SCST_SENSE_ASCx_VALID,
-+ 0, 0x2a, 0x01) ||
-+ scst_analyze_sense(cmd->sense, cmd->sense_valid_len,
-+ SCST_SENSE_ASC_VALID,
-+ 0, 0x29, 0) /* reset */ ||
-+ scst_analyze_sense(cmd->sense, cmd->sense_valid_len,
-+ SCST_SENSE_ASC_VALID,
-+ 0, 0x28, 0) /* medium changed */ ||
-+ /* cleared by another ini (just in case) */
-+ scst_analyze_sense(cmd->sense, cmd->sense_valid_len,
-+ SCST_SENSE_ASC_VALID,
-+ 0, 0x2F, 0))) {
-+ int atomic = scst_cmd_atomic(cmd);
-+ if (atomic) {
-+ TRACE_DBG("Possible parameters changed UA %x: "
-+ "thread context required", cmd->sense[12]);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+
-+ TRACE(TRACE_SCSI, "Possible parameters changed UA %x "
-+ "(LUN %lld): getting new parameters", cmd->sense[12],
-+ (long long unsigned int)cmd->lun);
-+
-+ scst_obtain_device_parameters(cmd->dev);
-+ } else
-+ BUG();
-+
-+ cmd->state = SCST_CMD_STATE_DEV_DONE;
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+static void scst_inc_check_expected_sn(struct scst_cmd *cmd)
-+{
-+ if (likely(cmd->sn_set))
-+ scst_inc_expected_sn(cmd->cur_order_data, cmd->sn_slot);
-+
-+ scst_make_deferred_commands_active(cmd->cur_order_data);
-+}
-+
-+static int scst_dev_done(struct scst_cmd *cmd)
-+{
-+ int res = SCST_CMD_STATE_RES_CONT_SAME;
-+ int state;
-+ struct scst_device *dev = cmd->dev;
-+
-+ TRACE_ENTRY();
-+
-+ state = SCST_CMD_STATE_PRE_XMIT_RESP;
-+
-+ if (likely(!scst_is_cmd_fully_local(cmd)) &&
-+ likely(dev->handler->dev_done != NULL)) {
-+ int rc;
-+
-+ if (unlikely(!dev->handler->dev_done_atomic &&
-+ scst_cmd_atomic(cmd))) {
-+ /*
-+ * It shouldn't be because of the SCST_TGT_DEV_AFTER_*
-+ * optimization.
-+ */
-+ TRACE_MGMT_DBG("Dev handler %s dev_done() needs thread "
-+ "context, rescheduling", dev->handler->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+
-+ TRACE_DBG("Calling dev handler %s dev_done(%p)",
-+ dev->handler->name, cmd);
-+ scst_set_cur_start(cmd);
-+ rc = dev->handler->dev_done(cmd);
-+ scst_set_dev_done_time(cmd);
-+ TRACE_DBG("Dev handler %s dev_done() returned %d",
-+ dev->handler->name, rc);
-+ if (rc != SCST_CMD_STATE_DEFAULT)
-+ state = rc;
-+ }
-+
-+ switch (state) {
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ case SCST_CMD_STATE_PRE_XMIT_RESP:
-+ case SCST_CMD_STATE_PARSE:
-+ case SCST_CMD_STATE_PREPARE_SPACE:
-+ case SCST_CMD_STATE_RDY_TO_XFER:
-+ case SCST_CMD_STATE_TGT_PRE_EXEC:
-+ case SCST_CMD_STATE_SEND_FOR_EXEC:
-+ case SCST_CMD_STATE_START_EXEC:
-+ case SCST_CMD_STATE_LOCAL_EXEC:
-+ case SCST_CMD_STATE_REAL_EXEC:
-+ case SCST_CMD_STATE_PRE_DEV_DONE:
-+ case SCST_CMD_STATE_MODE_SELECT_CHECKS:
-+ case SCST_CMD_STATE_DEV_DONE:
-+ case SCST_CMD_STATE_XMIT_RESP:
-+ case SCST_CMD_STATE_FINISHED:
-+ case SCST_CMD_STATE_FINISHED_INTERNAL:
-+#else
-+ default:
-+#endif
-+ cmd->state = state;
-+ break;
-+ case SCST_CMD_STATE_NEED_THREAD_CTX:
-+ TRACE_DBG("Dev handler %s dev_done() requested "
-+ "thread context, rescheduling",
-+ dev->handler->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ default:
-+ if (state >= 0) {
-+ PRINT_ERROR("Dev handler %s dev_done() returned "
-+ "invalid cmd state %d",
-+ dev->handler->name, state);
-+ } else {
-+ PRINT_ERROR("Dev handler %s dev_done() returned "
-+ "error %d", dev->handler->name,
-+ state);
-+ }
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ break;
-+#endif
-+ }
-+
-+ scst_check_unblock_dev(cmd);
-+
-+ if (cmd->inc_expected_sn_on_done && cmd->sent_for_exec)
-+ scst_inc_check_expected_sn(cmd);
-+
-+ if (unlikely(cmd->internal))
-+ cmd->state = SCST_CMD_STATE_FINISHED_INTERNAL;
-+
-+#ifndef CONFIG_SCST_TEST_IO_IN_SIRQ
-+ if (cmd->state != SCST_CMD_STATE_PRE_XMIT_RESP) {
-+ /* We can't allow atomic command on the exec stages */
-+ if (scst_cmd_atomic(cmd)) {
-+ switch (state) {
-+ case SCST_CMD_STATE_TGT_PRE_EXEC:
-+ case SCST_CMD_STATE_SEND_FOR_EXEC:
-+ case SCST_CMD_STATE_START_EXEC:
-+ case SCST_CMD_STATE_LOCAL_EXEC:
-+ case SCST_CMD_STATE_REAL_EXEC:
-+ TRACE_DBG("Atomic context and redirect, "
-+ "rescheduling (cmd %p)", cmd);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ break;
-+ }
-+ }
-+ }
-+#endif
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+static int scst_pre_xmit_response(struct scst_cmd *cmd)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ EXTRACHECKS_BUG_ON(cmd->internal);
-+
-+#ifdef CONFIG_SCST_DEBUG_TM
-+ if (cmd->tm_dbg_delayed &&
-+ !test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) {
-+ if (scst_cmd_atomic(cmd)) {
-+ TRACE_MGMT_DBG("%s",
-+ "DEBUG_TM delayed cmd needs a thread");
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ return res;
-+ }
-+ TRACE_MGMT_DBG("Delaying cmd %p (tag %llu) for 1 second",
-+ cmd, cmd->tag);
-+ schedule_timeout_uninterruptible(HZ);
-+ }
-+#endif
-+
-+ if (likely(cmd->tgt_dev != NULL)) {
-+ /*
-+ * Those counters protect from not getting too long processing
-+ * latency, so we should decrement them after cmd completed.
-+ */
-+ atomic_dec(&cmd->tgt_dev->tgt_dev_cmd_count);
-+#ifdef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT
-+ atomic_dec(&cmd->dev->dev_cmd_count);
-+#endif
-+ if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
-+ scst_on_hq_cmd_response(cmd);
-+
-+ if (unlikely(!cmd->sent_for_exec)) {
-+ TRACE_SN("cmd %p was not sent to mid-lev"
-+ " (sn %d, set %d)",
-+ cmd, cmd->sn, cmd->sn_set);
-+ scst_unblock_deferred(cmd->cur_order_data, cmd);
-+ cmd->sent_for_exec = 1;
-+ }
-+ }
-+
-+ cmd->done = 1;
-+ smp_mb(); /* to sync with scst_abort_cmd() */
-+
-+ if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)))
-+ scst_xmit_process_aborted_cmd(cmd);
-+ else if (unlikely(cmd->status == SAM_STAT_CHECK_CONDITION))
-+ scst_store_sense(cmd);
-+
-+ if (unlikely(test_bit(SCST_CMD_NO_RESP, &cmd->cmd_flags))) {
-+ TRACE_MGMT_DBG("Flag NO_RESP set for cmd %p (tag %llu), "
-+ "skipping", cmd, (long long unsigned int)cmd->tag);
-+ cmd->state = SCST_CMD_STATE_FINISHED;
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+ goto out;
-+ }
-+
-+ if (unlikely(cmd->resid_possible))
-+ scst_adjust_resp_data_len(cmd);
-+ else
-+ cmd->adjusted_resp_data_len = cmd->resp_data_len;
-+
-+ cmd->state = SCST_CMD_STATE_XMIT_RESP;
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+static int scst_xmit_response(struct scst_cmd *cmd)
-+{
-+ struct scst_tgt_template *tgtt = cmd->tgtt;
-+ int res, rc;
-+
-+ TRACE_ENTRY();
-+
-+ EXTRACHECKS_BUG_ON(cmd->internal);
-+
-+ if (unlikely(!tgtt->xmit_response_atomic &&
-+ scst_cmd_atomic(cmd))) {
-+ /*
-+ * It shouldn't be because of the SCST_TGT_DEV_AFTER_*
-+ * optimization.
-+ */
-+ TRACE_MGMT_DBG("Target driver %s xmit_response() needs thread "
-+ "context, rescheduling", tgtt->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+
-+ while (1) {
-+ int finished_cmds = atomic_read(&cmd->tgt->finished_cmds);
-+
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+ cmd->state = SCST_CMD_STATE_XMIT_WAIT;
-+
-+ TRACE_DBG("Calling xmit_response(%p)", cmd);
-+
-+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
-+ if (trace_flag & TRACE_SND_BOT) {
-+ int i, j;
-+ struct scatterlist *sg;
-+ if (cmd->tgt_sg != NULL)
-+ sg = cmd->tgt_sg;
-+ else
-+ sg = cmd->sg;
-+ if (sg != NULL) {
-+ TRACE(TRACE_SND_BOT, "Xmitting data for cmd %p "
-+ "(sg_cnt %d, sg %p, sg[0].page %p, buf %p, "
-+ "resp len %d)", cmd, cmd->tgt_sg_cnt,
-+ sg, (void *)sg_page(&sg[0]), sg_virt(sg),
-+ cmd->resp_data_len);
-+ for (i = 0, j = 0; i < cmd->tgt_sg_cnt; ++i, ++j) {
-+ if (unlikely(sg_is_chain(&sg[j]))) {
-+ sg = sg_chain_ptr(&sg[j]);
-+ j = 0;
-+ }
-+ TRACE(TRACE_SND_BOT, "sg %d", j);
-+ PRINT_BUFF_FLAG(TRACE_SND_BOT,
-+ "Xmitting sg", sg_virt(&sg[j]),
-+ sg[j].length);
-+ }
-+ }
-+ }
-+#endif
-+
-+ if (tgtt->on_hw_pending_cmd_timeout != NULL) {
-+ struct scst_session *sess = cmd->sess;
-+ cmd->hw_pending_start = jiffies;
-+ cmd->cmd_hw_pending = 1;
-+ if (!test_bit(SCST_SESS_HW_PENDING_WORK_SCHEDULED, &sess->sess_aflags)) {
-+ TRACE_DBG("Sched HW pending work for sess %p "
-+ "(max time %d)", sess,
-+ tgtt->max_hw_pending_time);
-+ set_bit(SCST_SESS_HW_PENDING_WORK_SCHEDULED,
-+ &sess->sess_aflags);
-+ schedule_delayed_work(&sess->hw_pending_work,
-+ tgtt->max_hw_pending_time * HZ);
-+ }
-+ }
-+
-+ scst_set_cur_start(cmd);
-+
-+#ifdef CONFIG_SCST_DEBUG_RETRY
-+ if (((scst_random() % 100) == 77))
-+ rc = SCST_TGT_RES_QUEUE_FULL;
-+ else
-+#endif
-+ rc = tgtt->xmit_response(cmd);
-+ TRACE_DBG("xmit_response() returned %d", rc);
-+
-+ if (likely(rc == SCST_TGT_RES_SUCCESS))
-+ goto out;
-+
-+ scst_set_xmit_time(cmd);
-+
-+ cmd->cmd_hw_pending = 0;
-+
-+ /* Restore the previous state */
-+ cmd->state = SCST_CMD_STATE_XMIT_RESP;
-+
-+ switch (rc) {
-+ case SCST_TGT_RES_QUEUE_FULL:
-+ if (scst_queue_retry_cmd(cmd, finished_cmds) == 0)
-+ break;
-+ else
-+ continue;
-+
-+ case SCST_TGT_RES_NEED_THREAD_CTX:
-+ TRACE_DBG("Target driver %s xmit_response() "
-+ "requested thread context, rescheduling",
-+ tgtt->name);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+
-+ default:
-+ goto out_error;
-+ }
-+ break;
-+ }
-+
-+out:
-+ /* Caution: cmd can be already dead here */
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+
-+out_error:
-+ if (rc == SCST_TGT_RES_FATAL_ERROR) {
-+ PRINT_ERROR("Target driver %s xmit_response() returned "
-+ "fatal error", tgtt->name);
-+ } else {
-+ PRINT_ERROR("Target driver %s xmit_response() returned "
-+ "invalid value %d", tgtt->name, rc);
-+ }
-+ scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
-+ cmd->state = SCST_CMD_STATE_FINISHED;
-+ res = SCST_CMD_STATE_RES_CONT_SAME;
-+ goto out;
-+}
-+
-+/**
-+ * scst_tgt_cmd_done() - the command's processing done
-+ * @cmd: SCST command
-+ * @pref_context: preferred command execution context
-+ *
-+ * Description:
-+ * Notifies SCST that the driver sent the response and the command
-+ * can be freed now. Don't forget to set the delivery status, if it
-+ * isn't success, using scst_set_delivery_status() before calling
-+ * this function. The third argument sets preferred command execution
-+ * context (see SCST_CONTEXT_* constants for details)
-+ */
-+void scst_tgt_cmd_done(struct scst_cmd *cmd,
-+ enum scst_exec_context pref_context)
-+{
-+ TRACE_ENTRY();
-+
-+ BUG_ON(cmd->state != SCST_CMD_STATE_XMIT_WAIT);
-+
-+ scst_set_xmit_time(cmd);
-+
-+ cmd->cmd_hw_pending = 0;
-+
-+ if (unlikely(cmd->tgt_dev == NULL))
-+ pref_context = SCST_CONTEXT_THREAD;
-+
-+ cmd->state = SCST_CMD_STATE_FINISHED;
-+
-+ scst_process_redirect_cmd(cmd, pref_context, 1);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL(scst_tgt_cmd_done);
-+
-+static int scst_finish_cmd(struct scst_cmd *cmd)
-+{
-+ int res;
-+ struct scst_session *sess = cmd->sess;
-+ struct scst_io_stat_entry *stat;
-+
-+ TRACE_ENTRY();
-+
-+ scst_update_lat_stats(cmd);
-+
-+ if (unlikely(cmd->delivery_status != SCST_CMD_DELIVERY_SUCCESS)) {
-+ if ((cmd->tgt_dev != NULL) &&
-+ scst_is_ua_sense(cmd->sense, cmd->sense_valid_len)) {
-+ /* This UA delivery failed, so we need to requeue it */
-+ if (scst_cmd_atomic(cmd) &&
-+ scst_is_ua_global(cmd->sense, cmd->sense_valid_len)) {
-+ TRACE_MGMT_DBG("Requeuing of global UA for "
-+ "failed cmd %p needs a thread", cmd);
-+ res = SCST_CMD_STATE_RES_NEED_THREAD;
-+ goto out;
-+ }
-+ scst_requeue_ua(cmd);
-+ }
-+ }
-+
-+ atomic_dec(&sess->sess_cmd_count);
-+
-+ spin_lock_irq(&sess->sess_list_lock);
-+
-+ stat = &sess->io_stats[cmd->data_direction];
-+ stat->cmd_count++;
-+ stat->io_byte_count += cmd->bufflen + cmd->out_bufflen;
-+
-+ list_del(&cmd->sess_cmd_list_entry);
-+
-+ /*
-+ * Done under sess_list_lock to sync with scst_abort_cmd() without
-+ * using extra barrier.
-+ */
-+ cmd->finished = 1;
-+
-+ spin_unlock_irq(&sess->sess_list_lock);
-+
-+ if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
-+ TRACE_MGMT_DBG("Aborted cmd %p finished (cmd_ref %d)",
-+ cmd, atomic_read(&cmd->cmd_ref));
-+
-+ scst_finish_cmd_mgmt(cmd);
-+ }
-+
-+ __scst_cmd_put(cmd);
-+
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+/*
-+ * No locks, but it must be externally serialized (see comment for
-+ * scst_cmd_init_done() in scst.h)
-+ */
-+static void scst_cmd_set_sn(struct scst_cmd *cmd)
-+{
-+ struct scst_order_data *order_data = cmd->cur_order_data;
-+ unsigned long flags;
-+
-+ TRACE_ENTRY();
-+
-+ if (scst_is_implicit_hq_cmd(cmd) &&
-+ likely(cmd->queue_type == SCST_CMD_QUEUE_SIMPLE)) {
-+ TRACE_SN("Implicit HQ cmd %p", cmd);
-+ cmd->queue_type = SCST_CMD_QUEUE_HEAD_OF_QUEUE;
-+ }
-+
-+ EXTRACHECKS_BUG_ON(cmd->sn_set || cmd->hq_cmd_inced);
-+
-+ /* Optimized for lockless fast path */
-+
-+ scst_check_debug_sn(cmd);
-+
-+#ifdef CONFIG_SCST_STRICT_SERIALIZING
-+ cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
-+#endif
-+
-+ if (cmd->dev->queue_alg == SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER) {
-+ /*
-+ * Not the best way, but good enough until there is a
-+ * possibility to specify queue type during pass-through
-+ * commands submission.
-+ */
-+ cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
-+ }
-+
-+ switch (cmd->queue_type) {
-+ case SCST_CMD_QUEUE_SIMPLE:
-+ case SCST_CMD_QUEUE_UNTAGGED:
-+ if (likely(order_data->num_free_sn_slots >= 0)) {
-+ /*
-+ * atomic_inc_return() implies memory barrier to sync
-+ * with scst_inc_expected_sn()
-+ */
-+ if (atomic_inc_return(order_data->cur_sn_slot) == 1) {
-+ order_data->curr_sn++;
-+ TRACE_SN("Incremented curr_sn %d",
-+ order_data->curr_sn);
-+ }
-+ cmd->sn_slot = order_data->cur_sn_slot;
-+ cmd->sn = order_data->curr_sn;
-+
-+ order_data->prev_cmd_ordered = 0;
-+ } else {
-+ TRACE(TRACE_MINOR, "***WARNING*** Not enough SN slots "
-+ "%zd", ARRAY_SIZE(order_data->sn_slots));
-+ goto ordered;
-+ }
-+ break;
-+
-+ case SCST_CMD_QUEUE_ORDERED:
-+ TRACE_SN("ORDERED cmd %p (op %x)", cmd, cmd->cdb[0]);
-+ordered:
-+ if (!order_data->prev_cmd_ordered) {
-+ spin_lock_irqsave(&order_data->sn_lock, flags);
-+ if (order_data->num_free_sn_slots >= 0) {
-+ order_data->num_free_sn_slots--;
-+ if (order_data->num_free_sn_slots >= 0) {
-+ int i = 0;
-+ /* Commands can finish in any order, so
-+ * we don't know which slot is empty.
-+ */
-+ while (1) {
-+ order_data->cur_sn_slot++;
-+ if (order_data->cur_sn_slot ==
-+ order_data->sn_slots + ARRAY_SIZE(order_data->sn_slots))
-+ order_data->cur_sn_slot = order_data->sn_slots;
-+
-+ if (atomic_read(order_data->cur_sn_slot) == 0)
-+ break;
-+
-+ i++;
-+ BUG_ON(i == ARRAY_SIZE(order_data->sn_slots));
-+ }
-+ TRACE_SN("New cur SN slot %zd",
-+ order_data->cur_sn_slot -
-+ order_data->sn_slots);
-+ }
-+ }
-+ spin_unlock_irqrestore(&order_data->sn_lock, flags);
-+ }
-+ order_data->prev_cmd_ordered = 1;
-+ order_data->curr_sn++;
-+ cmd->sn = order_data->curr_sn;
-+ break;
-+
-+ case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
-+ TRACE_SN("HQ cmd %p (op %x)", cmd, cmd->cdb[0]);
-+ spin_lock_irqsave(&order_data->sn_lock, flags);
-+ order_data->hq_cmd_count++;
-+ spin_unlock_irqrestore(&order_data->sn_lock, flags);
-+ cmd->hq_cmd_inced = 1;
-+ goto out;
-+
-+ default:
-+ BUG();
-+ }
-+
-+ TRACE_SN("cmd(%p)->sn: %d (order_data %p, *cur_sn_slot %d, "
-+ "num_free_sn_slots %d, prev_cmd_ordered %ld, "
-+ "cur_sn_slot %zd)", cmd, cmd->sn, order_data,
-+ atomic_read(order_data->cur_sn_slot),
-+ order_data->num_free_sn_slots, order_data->prev_cmd_ordered,
-+ order_data->cur_sn_slot - order_data->sn_slots);
-+
-+ cmd->sn_set = 1;
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/*
-+ * Returns 0 on success, > 0 when we need to wait for unblock,
-+ * < 0 if there is no device (lun) or device type handler.
-+ *
-+ * No locks, but might be on IRQ, protection is done by the
-+ * suspended activity.
-+ */
-+static int scst_translate_lun(struct scst_cmd *cmd)
-+{
-+ struct scst_tgt_dev *tgt_dev = NULL;
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ cmd->cpu_cmd_counter = scst_get();
-+
-+ if (likely(!test_bit(SCST_FLAG_SUSPENDED, &scst_flags))) {
-+ struct list_head *head =
-+ &cmd->sess->sess_tgt_dev_list[SESS_TGT_DEV_LIST_HASH_FN(cmd->lun)];
-+ TRACE_DBG("Finding tgt_dev for cmd %p (lun %lld)", cmd,
-+ (long long unsigned int)cmd->lun);
-+ res = -1;
-+ list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
-+ if (tgt_dev->lun == cmd->lun) {
-+ TRACE_DBG("tgt_dev %p found", tgt_dev);
-+
-+ if (unlikely(tgt_dev->dev->handler ==
-+ &scst_null_devtype)) {
-+ PRINT_INFO("Dev handler for device "
-+ "%lld is NULL, the device will not "
-+ "be visible remotely",
-+ (long long unsigned int)cmd->lun);
-+ break;
-+ }
-+
-+ cmd->cmd_threads = tgt_dev->active_cmd_threads;
-+ cmd->tgt_dev = tgt_dev;
-+ cmd->cur_order_data = tgt_dev->curr_order_data;
-+ cmd->dev = tgt_dev->dev;
-+
-+ res = 0;
-+ break;
-+ }
-+ }
-+ if (res != 0) {
-+ TRACE(TRACE_MINOR,
-+ "tgt_dev for LUN %lld not found, command to "
-+ "unexisting LU (initiator %s, target %s)?",
-+ (long long unsigned int)cmd->lun,
-+ cmd->sess->initiator_name, cmd->tgt->tgt_name);
-+ scst_put(cmd->cpu_cmd_counter);
-+ }
-+ } else {
-+ TRACE_MGMT_DBG("%s", "FLAG SUSPENDED set, skipping");
-+ scst_put(cmd->cpu_cmd_counter);
-+ res = 1;
-+ }
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/*
-+ * No locks, but might be on IRQ.
-+ *
-+ * Returns 0 on success, > 0 when we need to wait for unblock,
-+ * < 0 if there is no device (lun) or device type handler.
-+ */
-+static int __scst_init_cmd(struct scst_cmd *cmd)
-+{
-+ int res = 0;
-+
-+ TRACE_ENTRY();
-+
-+ res = scst_translate_lun(cmd);
-+ if (likely(res == 0)) {
-+ int cnt;
-+ bool failure = false;
-+
-+ cmd->state = SCST_CMD_STATE_PARSE;
-+
-+ cnt = atomic_inc_return(&cmd->tgt_dev->tgt_dev_cmd_count);
-+ if (unlikely(cnt > SCST_MAX_TGT_DEV_COMMANDS)) {
-+ TRACE(TRACE_FLOW_CONTROL,
-+ "Too many pending commands (%d) in "
-+ "session, returning BUSY to initiator \"%s\"",
-+ cnt, (cmd->sess->initiator_name[0] == '\0') ?
-+ "Anonymous" : cmd->sess->initiator_name);
-+ failure = true;
-+ }
-+
-+#ifdef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT
-+ cnt = atomic_inc_return(&cmd->dev->dev_cmd_count);
-+ if (unlikely(cnt > SCST_MAX_DEV_COMMANDS)) {
-+ if (!failure) {
-+ TRACE(TRACE_FLOW_CONTROL,
-+ "Too many pending device "
-+ "commands (%d), returning BUSY to "
-+ "initiator \"%s\"", cnt,
-+ (cmd->sess->initiator_name[0] == '\0') ?
-+ "Anonymous" :
-+ cmd->sess->initiator_name);
-+ failure = true;
-+ }
-+ }
-+#endif
-+
-+ if (unlikely(failure))
-+ goto out_busy;
-+
-+ /*
-+ * SCST_IMPLICIT_HQ for unknown commands not implemented for
-+ * case when set_sn_on_restart_cmd not set, because custom parse
-+ * can reorder commands due to multithreaded processing. To
-+ * implement it we need to implement all unknown commands as
-+ * ORDERED in the beginning and post parse reprocess of
-+ * queue_type to change it if needed. ToDo.
-+ */
-+ scst_pre_parse(cmd);
-+
-+ if (!cmd->set_sn_on_restart_cmd)
-+ scst_cmd_set_sn(cmd);
-+ } else if (res < 0) {
-+ TRACE_DBG("Finishing cmd %p", cmd);
-+ scst_set_cmd_error(cmd,
-+ SCST_LOAD_SENSE(scst_sense_lun_not_supported));
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ } else
-+ goto out;
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_busy:
-+ scst_set_busy(cmd);
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ goto out;
-+}
-+
-+/* Called under scst_init_lock and IRQs disabled */
-+static void scst_do_job_init(void)
-+ __releases(&scst_init_lock)
-+ __acquires(&scst_init_lock)
-+{
-+ struct scst_cmd *cmd;
-+ int susp;
-+
-+ TRACE_ENTRY();
-+
-+restart:
-+ /*
-+ * There is no need for read barrier here, because we don't care where
-+ * this check will be done.
-+ */
-+ susp = test_bit(SCST_FLAG_SUSPENDED, &scst_flags);
-+ if (scst_init_poll_cnt > 0)
-+ scst_init_poll_cnt--;
-+
-+ list_for_each_entry(cmd, &scst_init_cmd_list, cmd_list_entry) {
-+ int rc;
-+ if (susp && !test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))
-+ continue;
-+ if (!test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) {
-+ spin_unlock_irq(&scst_init_lock);
-+ rc = __scst_init_cmd(cmd);
-+ spin_lock_irq(&scst_init_lock);
-+ if (rc > 0) {
-+ TRACE_MGMT_DBG("%s",
-+ "FLAG SUSPENDED set, restarting");
-+ goto restart;
-+ }
-+ } else {
-+ TRACE_MGMT_DBG("Aborting not inited cmd %p (tag %llu)",
-+ cmd, (long long unsigned int)cmd->tag);
-+ scst_set_cmd_abnormal_done_state(cmd);
-+ }
-+
-+ /*
-+ * Deleting cmd from init cmd list after __scst_init_cmd()
-+ * is necessary to keep the check in scst_init_cmd() correct
-+ * to preserve the commands order.
-+ *
-+ * We don't care about the race, when init cmd list is empty
-+ * and one command detected that it just was not empty, so
-+ * it's inserting to it, but another command at the same time
-+ * seeing init cmd list empty and goes directly, because it
-+ * could affect only commands from the same initiator to the
-+ * same tgt_dev, but scst_cmd_init_done*() doesn't guarantee
-+ * the order in case of simultaneous such calls anyway.
-+ */
-+ TRACE_MGMT_DBG("Deleting cmd %p from init cmd list", cmd);
-+ smp_wmb(); /* enforce the required order */
-+ list_del(&cmd->cmd_list_entry);
-+ spin_unlock(&scst_init_lock);
-+
-+ spin_lock(&cmd->cmd_threads->cmd_list_lock);
-+ TRACE_MGMT_DBG("Adding cmd %p to active cmd list", cmd);
-+ if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
-+ list_add(&cmd->cmd_list_entry,
-+ &cmd->cmd_threads->active_cmd_list);
-+ else
-+ list_add_tail(&cmd->cmd_list_entry,
-+ &cmd->cmd_threads->active_cmd_list);
-+ wake_up(&cmd->cmd_threads->cmd_list_waitQ);
-+ spin_unlock(&cmd->cmd_threads->cmd_list_lock);
-+
-+ spin_lock(&scst_init_lock);
-+ goto restart;
-+ }
-+
-+ /* It isn't really needed, but let's keep it */
-+ if (susp != test_bit(SCST_FLAG_SUSPENDED, &scst_flags))
-+ goto restart;
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+static inline int test_init_cmd_list(void)
-+{
-+ int res = (!list_empty(&scst_init_cmd_list) &&
-+ !test_bit(SCST_FLAG_SUSPENDED, &scst_flags)) ||
-+ unlikely(kthread_should_stop()) ||
-+ (scst_init_poll_cnt > 0);
-+ return res;
-+}
-+
-+int scst_init_thread(void *arg)
-+{
-+ TRACE_ENTRY();
-+
-+ PRINT_INFO("Init thread started, PID %d", current->pid);
-+
-+ current->flags |= PF_NOFREEZE;
-+
-+ set_user_nice(current, -10);
-+
-+ spin_lock_irq(&scst_init_lock);
-+ while (!kthread_should_stop()) {
-+ wait_queue_t wait;
-+ init_waitqueue_entry(&wait, current);
-+
-+ if (!test_init_cmd_list()) {
-+ add_wait_queue_exclusive(&scst_init_cmd_list_waitQ,
-+ &wait);
-+ for (;;) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (test_init_cmd_list())
-+ break;
-+ spin_unlock_irq(&scst_init_lock);
-+ schedule();
-+ spin_lock_irq(&scst_init_lock);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&scst_init_cmd_list_waitQ, &wait);
-+ }
-+ scst_do_job_init();
-+ }
-+ spin_unlock_irq(&scst_init_lock);
-+
-+ /*
-+ * If kthread_should_stop() is true, we are guaranteed to be
-+ * on the module unload, so scst_init_cmd_list must be empty.
-+ */
-+ BUG_ON(!list_empty(&scst_init_cmd_list));
-+
-+ PRINT_INFO("Init thread PID %d finished", current->pid);
-+
-+ TRACE_EXIT();
-+ return 0;
-+}
-+
-+/**
-+ * scst_process_active_cmd() - process active command
-+ *
-+ * Description:
-+ * Main SCST commands processing routing. Must be used only by dev handlers.
-+ *
-+ * Argument atomic is true, if function called in atomic context.
-+ *
-+ * Must be called with no locks held.
-+ */
-+void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ /*
-+ * Checkpatch will complain on the use of in_atomic() below. You
-+ * can safely ignore this warning since in_atomic() is used here only
-+ * for debugging purposes.
-+ */
-+ EXTRACHECKS_BUG_ON(in_irq() || irqs_disabled());
-+ EXTRACHECKS_WARN_ON((in_atomic() || in_interrupt()) && !atomic);
-+
-+ cmd->atomic = atomic;
-+
-+ TRACE_DBG("cmd %p, atomic %d", cmd, atomic);
-+
-+ do {
-+ switch (cmd->state) {
-+ case SCST_CMD_STATE_PARSE:
-+ res = scst_parse_cmd(cmd);
-+ break;
-+
-+ case SCST_CMD_STATE_PREPARE_SPACE:
-+ res = scst_prepare_space(cmd);
-+ break;
-+
-+ case SCST_CMD_STATE_PREPROCESSING_DONE:
-+ res = scst_preprocessing_done(cmd);
-+ break;
-+
-+ case SCST_CMD_STATE_RDY_TO_XFER:
-+ res = scst_rdy_to_xfer(cmd);
-+ break;
-+
-+ case SCST_CMD_STATE_TGT_PRE_EXEC:
-+ res = scst_tgt_pre_exec(cmd);
-+ break;
-+
-+ case SCST_CMD_STATE_SEND_FOR_EXEC:
-+ if (tm_dbg_check_cmd(cmd) != 0) {
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+ TRACE_MGMT_DBG("Skipping cmd %p (tag %llu), "
-+ "because of TM DBG delay", cmd,
-+ (long long unsigned int)cmd->tag);
-+ break;
-+ }
-+ res = scst_send_for_exec(&cmd);
-+ EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD);
-+ /*
-+ * !! At this point cmd, sess & tgt_dev can already be
-+ * freed !!
-+ */
-+ break;
-+
-+ case SCST_CMD_STATE_START_EXEC:
-+ res = scst_exec(&cmd);
-+ EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD);
-+ /*
-+ * !! At this point cmd, sess & tgt_dev can already be
-+ * freed !!
-+ */
-+ break;
-+
-+ case SCST_CMD_STATE_LOCAL_EXEC:
-+ res = scst_local_exec(cmd);
-+ EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD);
-+ /*
-+ * !! At this point cmd, sess & tgt_dev can already be
-+ * freed !!
-+ */
-+ break;
-+
-+ case SCST_CMD_STATE_REAL_EXEC:
-+ res = scst_real_exec(cmd);
-+ EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD);
-+ /*
-+ * !! At this point cmd, sess & tgt_dev can already be
-+ * freed !!
-+ */
-+ break;
-+
-+ case SCST_CMD_STATE_PRE_DEV_DONE:
-+ res = scst_pre_dev_done(cmd);
-+ EXTRACHECKS_BUG_ON((res == SCST_CMD_STATE_RES_NEED_THREAD) &&
-+ (cmd->state == SCST_CMD_STATE_PRE_DEV_DONE));
-+ break;
-+
-+ case SCST_CMD_STATE_MODE_SELECT_CHECKS:
-+ res = scst_mode_select_checks(cmd);
-+ break;
-+
-+ case SCST_CMD_STATE_DEV_DONE:
-+ res = scst_dev_done(cmd);
-+ break;
-+
-+ case SCST_CMD_STATE_PRE_XMIT_RESP:
-+ res = scst_pre_xmit_response(cmd);
-+ EXTRACHECKS_BUG_ON(res ==
-+ SCST_CMD_STATE_RES_NEED_THREAD);
-+ break;
-+
-+ case SCST_CMD_STATE_XMIT_RESP:
-+ res = scst_xmit_response(cmd);
-+ break;
-+
-+ case SCST_CMD_STATE_FINISHED:
-+ res = scst_finish_cmd(cmd);
-+ break;
-+
-+ case SCST_CMD_STATE_FINISHED_INTERNAL:
-+ res = scst_finish_internal_cmd(cmd);
-+ EXTRACHECKS_BUG_ON(res ==
-+ SCST_CMD_STATE_RES_NEED_THREAD);
-+ break;
-+
-+ default:
-+ PRINT_CRIT_ERROR("cmd (%p) in state %d, but shouldn't "
-+ "be", cmd, cmd->state);
-+ BUG();
-+ res = SCST_CMD_STATE_RES_CONT_NEXT;
-+ break;
-+ }
-+ } while (res == SCST_CMD_STATE_RES_CONT_SAME);
-+
-+ if (res == SCST_CMD_STATE_RES_CONT_NEXT) {
-+ /* None */
-+ } else if (res == SCST_CMD_STATE_RES_NEED_THREAD) {
-+ spin_lock_irq(&cmd->cmd_threads->cmd_list_lock);
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ switch (cmd->state) {
-+ case SCST_CMD_STATE_PARSE:
-+ case SCST_CMD_STATE_PREPARE_SPACE:
-+ case SCST_CMD_STATE_RDY_TO_XFER:
-+ case SCST_CMD_STATE_TGT_PRE_EXEC:
-+ case SCST_CMD_STATE_SEND_FOR_EXEC:
-+ case SCST_CMD_STATE_START_EXEC:
-+ case SCST_CMD_STATE_LOCAL_EXEC:
-+ case SCST_CMD_STATE_REAL_EXEC:
-+ case SCST_CMD_STATE_DEV_DONE:
-+ case SCST_CMD_STATE_XMIT_RESP:
-+#endif
-+ TRACE_DBG("Adding cmd %p to head of active cmd list",
-+ cmd);
-+ list_add(&cmd->cmd_list_entry,
-+ &cmd->cmd_threads->active_cmd_list);
-+#ifdef CONFIG_SCST_EXTRACHECKS
-+ break;
-+ default:
-+ PRINT_CRIT_ERROR("cmd %p is in invalid state %d)", cmd,
-+ cmd->state);
-+ spin_unlock_irq(&cmd->cmd_threads->cmd_list_lock);
-+ BUG();
-+ spin_lock_irq(&cmd->cmd_threads->cmd_list_lock);
-+ break;
-+ }
-+#endif
-+ wake_up(&cmd->cmd_threads->cmd_list_waitQ);
-+ spin_unlock_irq(&cmd->cmd_threads->cmd_list_lock);
-+ } else
-+ BUG();
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(scst_process_active_cmd);
-+
-+/* Called under cmd_list_lock and IRQs disabled */
-+static void scst_do_job_active(struct list_head *cmd_list,
-+ spinlock_t *cmd_list_lock, bool atomic)
-+ __releases(cmd_list_lock)
-+ __acquires(cmd_list_lock)
-+{
-+ TRACE_ENTRY();
-+
-+ while (!list_empty(cmd_list)) {
-+ struct scst_cmd *cmd = list_entry(cmd_list->next, typeof(*cmd),
-+ cmd_list_entry);
-+ TRACE_DBG("Deleting cmd %p from active cmd list", cmd);
-+ list_del(&cmd->cmd_list_entry);
-+ spin_unlock_irq(cmd_list_lock);
-+ scst_process_active_cmd(cmd, atomic);
-+ spin_lock_irq(cmd_list_lock);
-+ }
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+static inline int test_cmd_threads(struct scst_cmd_threads *p_cmd_threads)
-+{
-+ int res = !list_empty(&p_cmd_threads->active_cmd_list) ||
-+ unlikely(kthread_should_stop()) ||
-+ tm_dbg_is_release();
-+ return res;
-+}
-+
-+int scst_cmd_thread(void *arg)
-+{
-+ struct scst_cmd_threads *p_cmd_threads = arg;
-+
-+ TRACE_ENTRY();
-+
-+ PRINT_INFO("Processing thread %s (PID %d) started", current->comm,
-+ current->pid);
-+
-+#if 0
-+ set_user_nice(current, 10);
-+#endif
-+ current->flags |= PF_NOFREEZE;
-+
-+ mutex_lock(&p_cmd_threads->io_context_mutex);
-+
-+ WARN_ON(current->io_context);
-+
-+ if (p_cmd_threads != &scst_main_cmd_threads) {
-+ /*
-+ * For linked IO contexts io_context might be not NULL while
-+ * io_context 0.
-+ */
-+ if (p_cmd_threads->io_context == NULL) {
-+ p_cmd_threads->io_context = get_io_context(GFP_KERNEL, -1);
-+ TRACE_MGMT_DBG("Alloced new IO context %p "
-+ "(p_cmd_threads %p)",
-+ p_cmd_threads->io_context,
-+ p_cmd_threads);
-+ /*
-+ * Put the extra reference created by get_io_context()
-+ * because we don't need it.
-+ */
-+ put_io_context(p_cmd_threads->io_context);
-+ } else {
-+ current->io_context = ioc_task_link(p_cmd_threads->io_context);
-+ TRACE_MGMT_DBG("Linked IO context %p "
-+ "(p_cmd_threads %p)", p_cmd_threads->io_context,
-+ p_cmd_threads);
-+ }
-+ p_cmd_threads->io_context_refcnt++;
-+ }
-+
-+ mutex_unlock(&p_cmd_threads->io_context_mutex);
-+
-+ smp_wmb();
-+ p_cmd_threads->io_context_ready = true;
-+
-+ spin_lock_irq(&p_cmd_threads->cmd_list_lock);
-+ while (!kthread_should_stop()) {
-+ wait_queue_t wait;
-+ init_waitqueue_entry(&wait, current);
-+
-+ if (!test_cmd_threads(p_cmd_threads)) {
-+ add_wait_queue_exclusive_head(
-+ &p_cmd_threads->cmd_list_waitQ,
-+ &wait);
-+ for (;;) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (test_cmd_threads(p_cmd_threads))
-+ break;
-+ spin_unlock_irq(&p_cmd_threads->cmd_list_lock);
-+ schedule();
-+ spin_lock_irq(&p_cmd_threads->cmd_list_lock);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&p_cmd_threads->cmd_list_waitQ, &wait);
-+ }
-+
-+ if (tm_dbg_is_release()) {
-+ spin_unlock_irq(&p_cmd_threads->cmd_list_lock);
-+ tm_dbg_check_released_cmds();
-+ spin_lock_irq(&p_cmd_threads->cmd_list_lock);
-+ }
-+
-+ scst_do_job_active(&p_cmd_threads->active_cmd_list,
-+ &p_cmd_threads->cmd_list_lock, false);
-+ }
-+ spin_unlock_irq(&p_cmd_threads->cmd_list_lock);
-+
-+ if (p_cmd_threads != &scst_main_cmd_threads) {
-+ mutex_lock(&p_cmd_threads->io_context_mutex);
-+ if (--p_cmd_threads->io_context_refcnt == 0)
-+ p_cmd_threads->io_context = NULL;
-+ mutex_unlock(&p_cmd_threads->io_context_mutex);
-+ }
-+
-+ PRINT_INFO("Processing thread %s (PID %d) finished", current->comm,
-+ current->pid);
-+
-+ TRACE_EXIT();
-+ return 0;
-+}
-+
-+void scst_cmd_tasklet(long p)
-+{
-+ struct scst_percpu_info *i = (struct scst_percpu_info *)p;
-+
-+ TRACE_ENTRY();
-+
-+ spin_lock_irq(&i->tasklet_lock);
-+ scst_do_job_active(&i->tasklet_cmd_list, &i->tasklet_lock, true);
-+ spin_unlock_irq(&i->tasklet_lock);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/*
-+ * Returns 0 on success, < 0 if there is no device handler or
-+ * > 0 if SCST_FLAG_SUSPENDED set and SCST_FLAG_SUSPENDING - not.
-+ * No locks, protection is done by the suspended activity.
-+ */
-+static int scst_mgmt_translate_lun(struct scst_mgmt_cmd *mcmd)
-+{
-+ struct scst_tgt_dev *tgt_dev = NULL;
-+ struct list_head *head;
-+ int res = -1;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_DBG("Finding tgt_dev for mgmt cmd %p (lun %lld)", mcmd,
-+ (long long unsigned int)mcmd->lun);
-+
-+ mcmd->cpu_cmd_counter = scst_get();
-+
-+ if (unlikely(test_bit(SCST_FLAG_SUSPENDED, &scst_flags) &&
-+ !test_bit(SCST_FLAG_SUSPENDING, &scst_flags))) {
-+ TRACE_MGMT_DBG("%s", "FLAG SUSPENDED set, skipping");
-+ scst_put(mcmd->cpu_cmd_counter);
-+ res = 1;
-+ goto out;
-+ }
-+
-+ head = &mcmd->sess->sess_tgt_dev_list[SESS_TGT_DEV_LIST_HASH_FN(mcmd->lun)];
-+ list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
-+ if (tgt_dev->lun == mcmd->lun) {
-+ TRACE_DBG("tgt_dev %p found", tgt_dev);
-+ mcmd->mcmd_tgt_dev = tgt_dev;
-+ res = 0;
-+ break;
-+ }
-+ }
-+ if (mcmd->mcmd_tgt_dev == NULL)
-+ scst_put(mcmd->cpu_cmd_counter);
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+/* No locks */
-+void scst_done_cmd_mgmt(struct scst_cmd *cmd)
-+{
-+ struct scst_mgmt_cmd_stub *mstb, *t;
-+ bool wake = 0;
-+ unsigned long flags;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_MGMT_DBG("cmd %p done (tag %llu)",
-+ cmd, (long long unsigned int)cmd->tag);
-+
-+ spin_lock_irqsave(&scst_mcmd_lock, flags);
-+
-+ list_for_each_entry_safe(mstb, t, &cmd->mgmt_cmd_list,
-+ cmd_mgmt_cmd_list_entry) {
-+ struct scst_mgmt_cmd *mcmd;
-+
-+ if (!mstb->done_counted)
-+ continue;
-+
-+ mcmd = mstb->mcmd;
-+ TRACE_MGMT_DBG("mcmd %p, mcmd->cmd_done_wait_count %d",
-+ mcmd, mcmd->cmd_done_wait_count);
-+
-+ mcmd->cmd_done_wait_count--;
-+
-+ BUG_ON(mcmd->cmd_done_wait_count < 0);
-+
-+ if (mcmd->cmd_done_wait_count > 0) {
-+ TRACE_MGMT_DBG("cmd_done_wait_count(%d) not 0, "
-+ "skipping", mcmd->cmd_done_wait_count);
-+ goto check_free;
-+ }
-+
-+ if (mcmd->state == SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_DONE) {
-+ mcmd->state = SCST_MCMD_STATE_AFFECTED_CMDS_DONE;
-+ TRACE_MGMT_DBG("Adding mgmt cmd %p to active mgmt cmd "
-+ "list", mcmd);
-+ list_add_tail(&mcmd->mgmt_cmd_list_entry,
-+ &scst_active_mgmt_cmd_list);
-+ wake = 1;
-+ }
-+
-+check_free:
-+ if (!mstb->finish_counted) {
-+ TRACE_DBG("Releasing mstb %p", mstb);
-+ list_del(&mstb->cmd_mgmt_cmd_list_entry);
-+ mempool_free(mstb, scst_mgmt_stub_mempool);
-+ }
-+ }
-+
-+ spin_unlock_irqrestore(&scst_mcmd_lock, flags);
-+
-+ if (wake)
-+ wake_up(&scst_mgmt_cmd_list_waitQ);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/* Called under scst_mcmd_lock and IRQs disabled */
-+static void __scst_dec_finish_wait_count(struct scst_mgmt_cmd *mcmd, bool *wake)
-+{
-+ TRACE_ENTRY();
-+
-+ mcmd->cmd_finish_wait_count--;
-+
-+ BUG_ON(mcmd->cmd_finish_wait_count < 0);
-+
-+ if (mcmd->cmd_finish_wait_count > 0) {
-+ TRACE_MGMT_DBG("cmd_finish_wait_count(%d) not 0, "
-+ "skipping", mcmd->cmd_finish_wait_count);
-+ goto out;
-+ }
-+
-+ if (mcmd->cmd_done_wait_count > 0) {
-+ TRACE_MGMT_DBG("cmd_done_wait_count(%d) not 0, "
-+ "skipping", mcmd->cmd_done_wait_count);
-+ goto out;
-+ }
-+
-+ if (mcmd->state == SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_FINISHED) {
-+ mcmd->state = SCST_MCMD_STATE_DONE;
-+ TRACE_MGMT_DBG("Adding mgmt cmd %p to active mgmt cmd "
-+ "list", mcmd);
-+ list_add_tail(&mcmd->mgmt_cmd_list_entry,
-+ &scst_active_mgmt_cmd_list);
-+ *wake = true;
-+ }
-+
-+out:
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/**
-+ * scst_prepare_async_mcmd() - prepare async management command
-+ *
-+ * Notifies SCST that management command is going to be async, i.e.
-+ * will be completed in another context.
-+ *
-+ * No SCST locks supposed to be held on entrance.
-+ */
-+void scst_prepare_async_mcmd(struct scst_mgmt_cmd *mcmd)
-+{
-+ unsigned long flags;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_MGMT_DBG("Preparing mcmd %p for async execution "
-+ "(cmd_finish_wait_count %d)", mcmd,
-+ mcmd->cmd_finish_wait_count);
-+
-+ spin_lock_irqsave(&scst_mcmd_lock, flags);
-+ mcmd->cmd_finish_wait_count++;
-+ spin_unlock_irqrestore(&scst_mcmd_lock, flags);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(scst_prepare_async_mcmd);
-+
-+/**
-+ * scst_async_mcmd_completed() - async management command completed
-+ *
-+ * Notifies SCST that async management command, prepared by
-+ * scst_prepare_async_mcmd(), completed.
-+ *
-+ * No SCST locks supposed to be held on entrance.
-+ */
-+void scst_async_mcmd_completed(struct scst_mgmt_cmd *mcmd, int status)
-+{
-+ unsigned long flags;
-+ bool wake = false;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_MGMT_DBG("Async mcmd %p completed (status %d)", mcmd, status);
-+
-+ spin_lock_irqsave(&scst_mcmd_lock, flags);
-+
-+ if (status != SCST_MGMT_STATUS_SUCCESS)
-+ mcmd->status = status;
-+
-+ __scst_dec_finish_wait_count(mcmd, &wake);
-+
-+ spin_unlock_irqrestore(&scst_mcmd_lock, flags);
-+
-+ if (wake)
-+ wake_up(&scst_mgmt_cmd_list_waitQ);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(scst_async_mcmd_completed);
-+
-+/* No locks */
-+static void scst_finish_cmd_mgmt(struct scst_cmd *cmd)
-+{
-+ struct scst_mgmt_cmd_stub *mstb, *t;
-+ bool wake = false;
-+ unsigned long flags;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_MGMT_DBG("cmd %p finished (tag %llu)",
-+ cmd, (long long unsigned int)cmd->tag);
-+
-+ spin_lock_irqsave(&scst_mcmd_lock, flags);
-+
-+ list_for_each_entry_safe(mstb, t, &cmd->mgmt_cmd_list,
-+ cmd_mgmt_cmd_list_entry) {
-+ struct scst_mgmt_cmd *mcmd = mstb->mcmd;
-+
-+ TRACE_MGMT_DBG("mcmd %p, mcmd->cmd_finish_wait_count %d", mcmd,
-+ mcmd->cmd_finish_wait_count);
-+
-+ BUG_ON(!mstb->finish_counted);
-+
-+ if (cmd->completed)
-+ mcmd->completed_cmd_count++;
-+
-+ __scst_dec_finish_wait_count(mcmd, &wake);
-+
-+ TRACE_DBG("Releasing mstb %p", mstb);
-+ list_del(&mstb->cmd_mgmt_cmd_list_entry);
-+ mempool_free(mstb, scst_mgmt_stub_mempool);
-+ }
-+
-+ spin_unlock_irqrestore(&scst_mcmd_lock, flags);
-+
-+ if (wake)
-+ wake_up(&scst_mgmt_cmd_list_waitQ);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+static int scst_call_dev_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
-+ struct scst_tgt_dev *tgt_dev, int set_status)
-+{
-+ int res = SCST_DEV_TM_NOT_COMPLETED;
-+ struct scst_dev_type *h = tgt_dev->dev->handler;
-+
-+ if (h->task_mgmt_fn) {
-+ TRACE_MGMT_DBG("Calling dev handler %s task_mgmt_fn(fn=%d)",
-+ h->name, mcmd->fn);
-+ res = h->task_mgmt_fn(mcmd, tgt_dev);
-+ TRACE_MGMT_DBG("Dev handler %s task_mgmt_fn() returned %d",
-+ h->name, res);
-+ if (set_status && (res != SCST_DEV_TM_NOT_COMPLETED))
-+ mcmd->status = res;
-+ }
-+ return res;
-+}
-+
-+static inline int scst_is_strict_mgmt_fn(int mgmt_fn)
-+{
-+ switch (mgmt_fn) {
-+#ifdef CONFIG_SCST_ABORT_CONSIDER_FINISHED_TASKS_AS_NOT_EXISTING
-+ case SCST_ABORT_TASK:
-+#endif
-+#if 0
-+ case SCST_ABORT_TASK_SET:
-+ case SCST_CLEAR_TASK_SET:
-+#endif
-+ return 1;
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/*
-+ * Must be called under sess_list_lock to sync with finished flag assignment in
-+ * scst_finish_cmd()
-+ */
-+void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
-+ bool other_ini, bool call_dev_task_mgmt_fn)
-+{
-+ unsigned long flags;
-+ static DEFINE_SPINLOCK(other_ini_lock);
-+
-+ TRACE_ENTRY();
-+
-+ TRACE(TRACE_SCSI|TRACE_MGMT_DEBUG, "Aborting cmd %p (tag %llu, op %x)",
-+ cmd, (long long unsigned int)cmd->tag, cmd->cdb[0]);
-+
-+ /* To protect from concurrent aborts */
-+ spin_lock_irqsave(&other_ini_lock, flags);
-+
-+ if (other_ini) {
-+ struct scst_device *dev = NULL;
-+
-+ /* Might be necessary if command aborted several times */
-+ if (!test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))
-+ set_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags);
-+
-+ /* Necessary for scst_xmit_process_aborted_cmd */
-+ if (cmd->dev != NULL)
-+ dev = cmd->dev;
-+ else if ((mcmd != NULL) && (mcmd->mcmd_tgt_dev != NULL))
-+ dev = mcmd->mcmd_tgt_dev->dev;
-+
-+ if (dev != NULL) {
-+ if (dev->tas)
-+ set_bit(SCST_CMD_DEVICE_TAS, &cmd->cmd_flags);
-+ } else
-+ PRINT_WARNING("Abort cmd %p from other initiator, but "
-+ "neither cmd, nor mcmd %p have tgt_dev set, so "
-+ "TAS information can be lost", cmd, mcmd);
-+ } else {
-+ /* Might be necessary if command aborted several times */
-+ clear_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags);
-+ }
-+
-+ set_bit(SCST_CMD_ABORTED, &cmd->cmd_flags);
-+
-+ spin_unlock_irqrestore(&other_ini_lock, flags);
-+
-+ /*
-+ * To sync with setting cmd->done in scst_pre_xmit_response() (with
-+ * scst_finish_cmd() we synced by using sess_list_lock) and with
-+ * setting UA for aborted cmd in scst_set_pending_UA().
-+ */
-+ smp_mb__after_set_bit();
-+
-+ if (cmd->tgt_dev == NULL) {
-+ spin_lock_irqsave(&scst_init_lock, flags);
-+ scst_init_poll_cnt++;
-+ spin_unlock_irqrestore(&scst_init_lock, flags);
-+ wake_up(&scst_init_cmd_list_waitQ);
-+ }
-+
-+ if (!cmd->finished && call_dev_task_mgmt_fn && (cmd->tgt_dev != NULL))
-+ scst_call_dev_task_mgmt_fn(mcmd, cmd->tgt_dev, 1);
-+
-+ spin_lock_irqsave(&scst_mcmd_lock, flags);
-+ if ((mcmd != NULL) && !cmd->finished) {
-+ struct scst_mgmt_cmd_stub *mstb;
-+
-+ mstb = mempool_alloc(scst_mgmt_stub_mempool, GFP_ATOMIC);
-+ if (mstb == NULL) {
-+ PRINT_CRIT_ERROR("Allocation of management command "
-+ "stub failed (mcmd %p, cmd %p)", mcmd, cmd);
-+ goto unlock;
-+ }
-+ memset(mstb, 0, sizeof(*mstb));
-+
-+ TRACE_DBG("mstb %p, mcmd %p", mstb, mcmd);
-+
-+ mstb->mcmd = mcmd;
-+
-+ /*
-+ * Delay the response until the command's finish in order to
-+ * guarantee that "no further responses from the task are sent
-+ * to the SCSI initiator port" after response from the TM
-+ * function is sent (SAM). Plus, we must wait here to be sure
-+ * that we won't receive double commands with the same tag.
-+ * Moreover, if we don't wait here, we might have a possibility
-+ * for data corruption, when aborted and reported as completed
-+ * command actually gets executed *after* new commands sent
-+ * after this TM command completed.
-+ */
-+
-+ if (cmd->sent_for_exec && !cmd->done) {
-+ TRACE_MGMT_DBG("cmd %p (tag %llu) is being executed",
-+ cmd, (long long unsigned int)cmd->tag);
-+ mstb->done_counted = 1;
-+ mcmd->cmd_done_wait_count++;
-+ }
-+
-+ /*
-+ * We don't have to wait the command's status delivery finish
-+ * to other initiators + it can affect MPIO failover.
-+ */
-+ if (!other_ini) {
-+ mstb->finish_counted = 1;
-+ mcmd->cmd_finish_wait_count++;
-+ }
-+
-+ if (mstb->done_counted || mstb->finish_counted) {
-+ TRACE(TRACE_SCSI|TRACE_MGMT_DEBUG, "cmd %p (tag %llu, "
-+ "sn %u) being executed/xmitted (state %d, "
-+ "op %x, proc time %ld sec., timeout %d sec.), "
-+ "deferring ABORT (cmd_done_wait_count %d, "
-+ "cmd_finish_wait_count %d)", cmd,
-+ (long long unsigned int)cmd->tag,
-+ cmd->sn, cmd->state, cmd->cdb[0],
-+ (long)(jiffies - cmd->start_time) / HZ,
-+ cmd->timeout / HZ, mcmd->cmd_done_wait_count,
-+ mcmd->cmd_finish_wait_count);
-+ /*
-+ * cmd can't die here or sess_list_lock already taken
-+ * and cmd is in the sess list
-+ */
-+ list_add_tail(&mstb->cmd_mgmt_cmd_list_entry,
-+ &cmd->mgmt_cmd_list);
-+ } else {
-+ /* We don't need to wait for this cmd */
-+ mempool_free(mstb, scst_mgmt_stub_mempool);
-+ }
-+
-+ if (cmd->tgtt->on_abort_cmd)
-+ cmd->tgtt->on_abort_cmd(cmd);
-+ }
-+
-+unlock:
-+ spin_unlock_irqrestore(&scst_mcmd_lock, flags);
-+
-+ tm_dbg_release_cmd(cmd);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/* No locks. Returns 0, if mcmd should be processed further. */
-+static int scst_set_mcmd_next_state(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res;
-+
-+ spin_lock_irq(&scst_mcmd_lock);
-+
-+ switch (mcmd->state) {
-+ case SCST_MCMD_STATE_INIT:
-+ case SCST_MCMD_STATE_EXEC:
-+ if (mcmd->cmd_done_wait_count == 0) {
-+ mcmd->state = SCST_MCMD_STATE_AFFECTED_CMDS_DONE;
-+ res = 0;
-+ } else {
-+ TRACE(TRACE_SCSI|TRACE_MGMT_DEBUG,
-+ "cmd_done_wait_count(%d) not 0, "
-+ "preparing to wait", mcmd->cmd_done_wait_count);
-+ mcmd->state = SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_DONE;
-+ res = -1;
-+ }
-+ break;
-+
-+ case SCST_MCMD_STATE_AFFECTED_CMDS_DONE:
-+ if (mcmd->cmd_finish_wait_count == 0) {
-+ mcmd->state = SCST_MCMD_STATE_DONE;
-+ res = 0;
-+ } else {
-+ TRACE(TRACE_SCSI|TRACE_MGMT_DEBUG,
-+ "cmd_finish_wait_count(%d) not 0, "
-+ "preparing to wait",
-+ mcmd->cmd_finish_wait_count);
-+ mcmd->state = SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_FINISHED;
-+ res = -1;
-+ }
-+ break;
-+
-+ case SCST_MCMD_STATE_DONE:
-+ mcmd->state = SCST_MCMD_STATE_FINISHED;
-+ res = 0;
-+ break;
-+
-+ default:
-+ PRINT_CRIT_ERROR("Wrong mcmd %p state %d (fn %d, "
-+ "cmd_finish_wait_count %d, cmd_done_wait_count %d)",
-+ mcmd, mcmd->state, mcmd->fn,
-+ mcmd->cmd_finish_wait_count, mcmd->cmd_done_wait_count);
-+ spin_unlock_irq(&scst_mcmd_lock);
-+ res = -1;
-+ BUG();
-+ goto out;
-+ }
-+
-+ spin_unlock_irq(&scst_mcmd_lock);
-+
-+out:
-+ return res;
-+}
-+
-+/* IRQs supposed to be disabled */
-+static bool __scst_check_unblock_aborted_cmd(struct scst_cmd *cmd,
-+ struct list_head *list_entry)
-+{
-+ bool res;
-+ if (test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) {
-+ list_del(list_entry);
-+ spin_lock(&cmd->cmd_threads->cmd_list_lock);
-+ list_add_tail(&cmd->cmd_list_entry,
-+ &cmd->cmd_threads->active_cmd_list);
-+ wake_up(&cmd->cmd_threads->cmd_list_waitQ);
-+ spin_unlock(&cmd->cmd_threads->cmd_list_lock);
-+ res = 1;
-+ } else
-+ res = 0;
-+ return res;
-+}
-+
-+static void scst_unblock_aborted_cmds(int scst_mutex_held)
-+{
-+ struct scst_device *dev;
-+
-+ TRACE_ENTRY();
-+
-+ if (!scst_mutex_held)
-+ mutex_lock(&scst_mutex);
-+
-+ list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
-+ struct scst_cmd *cmd, *tcmd;
-+ struct scst_tgt_dev *tgt_dev;
-+ spin_lock_bh(&dev->dev_lock);
-+ local_irq_disable();
-+ list_for_each_entry_safe(cmd, tcmd, &dev->blocked_cmd_list,
-+ blocked_cmd_list_entry) {
-+ if (__scst_check_unblock_aborted_cmd(cmd,
-+ &cmd->blocked_cmd_list_entry)) {
-+ TRACE_MGMT_DBG("Unblock aborted blocked cmd %p",
-+ cmd);
-+ }
-+ }
-+ local_irq_enable();
-+ spin_unlock_bh(&dev->dev_lock);
-+
-+ local_irq_disable();
-+ list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ struct scst_order_data *order_data = tgt_dev->curr_order_data;
-+ spin_lock(&order_data->sn_lock);
-+ list_for_each_entry_safe(cmd, tcmd,
-+ &order_data->deferred_cmd_list,
-+ sn_cmd_list_entry) {
-+ if (__scst_check_unblock_aborted_cmd(cmd,
-+ &cmd->sn_cmd_list_entry)) {
-+ TRACE_MGMT_DBG("Unblocked aborted SN "
-+ "cmd %p (sn %u)",
-+ cmd, cmd->sn);
-+ order_data->def_cmd_count--;
-+ }
-+ }
-+ spin_unlock(&order_data->sn_lock);
-+ }
-+ local_irq_enable();
-+ }
-+
-+ if (!scst_mutex_held)
-+ mutex_unlock(&scst_mutex);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+static void __scst_abort_task_set(struct scst_mgmt_cmd *mcmd,
-+ struct scst_tgt_dev *tgt_dev)
-+{
-+ struct scst_cmd *cmd;
-+ struct scst_session *sess = tgt_dev->sess;
-+ bool other_ini;
-+
-+ TRACE_ENTRY();
-+
-+ if ((mcmd->fn == SCST_PR_ABORT_ALL) &&
-+ (mcmd->origin_pr_cmd->sess != sess))
-+ other_ini = true;
-+ else
-+ other_ini = false;
-+
-+ spin_lock_irq(&sess->sess_list_lock);
-+
-+ TRACE_DBG("Searching in sess cmd list (sess=%p)", sess);
-+ list_for_each_entry(cmd, &sess->sess_cmd_list,
-+ sess_cmd_list_entry) {
-+ if ((mcmd->fn == SCST_PR_ABORT_ALL) &&
-+ (mcmd->origin_pr_cmd == cmd))
-+ continue;
-+ if ((cmd->tgt_dev == tgt_dev) ||
-+ ((cmd->tgt_dev == NULL) &&
-+ (cmd->lun == tgt_dev->lun))) {
-+ if (mcmd->cmd_sn_set) {
-+ BUG_ON(!cmd->tgt_sn_set);
-+ if (scst_sn_before(mcmd->cmd_sn, cmd->tgt_sn) ||
-+ (mcmd->cmd_sn == cmd->tgt_sn))
-+ continue;
-+ }
-+ scst_abort_cmd(cmd, mcmd, other_ini, 0);
-+ }
-+ }
-+ spin_unlock_irq(&sess->sess_list_lock);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/* Returns 0 if the command processing should be continued, <0 otherwise */
-+static int scst_abort_task_set(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res;
-+ struct scst_tgt_dev *tgt_dev = mcmd->mcmd_tgt_dev;
-+
-+ TRACE(TRACE_MGMT, "Aborting task set (lun=%lld, mcmd=%p)",
-+ (long long unsigned int)tgt_dev->lun, mcmd);
-+
-+ __scst_abort_task_set(mcmd, tgt_dev);
-+
-+ if (mcmd->fn == SCST_PR_ABORT_ALL) {
-+ struct scst_pr_abort_all_pending_mgmt_cmds_counter *pr_cnt =
-+ mcmd->origin_pr_cmd->pr_abort_counter;
-+ if (atomic_dec_and_test(&pr_cnt->pr_aborting_cnt))
-+ complete_all(&pr_cnt->pr_aborting_cmpl);
-+ }
-+
-+ tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev->dev, "ABORT TASK SET/PR ABORT", 0);
-+
-+ scst_unblock_aborted_cmds(0);
-+
-+ scst_call_dev_task_mgmt_fn(mcmd, tgt_dev, 0);
-+
-+ res = scst_set_mcmd_next_state(mcmd);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static int scst_is_cmd_belongs_to_dev(struct scst_cmd *cmd,
-+ struct scst_device *dev)
-+{
-+ struct scst_tgt_dev *tgt_dev = NULL;
-+ struct list_head *head;
-+ int res = 0;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_DBG("Finding match for dev %s and cmd %p (lun %lld)", dev->virt_name,
-+ cmd, (long long unsigned int)cmd->lun);
-+
-+ head = &cmd->sess->sess_tgt_dev_list[SESS_TGT_DEV_LIST_HASH_FN(cmd->lun)];
-+ list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
-+ if (tgt_dev->lun == cmd->lun) {
-+ TRACE_DBG("dev %s found", tgt_dev->dev->virt_name);
-+ res = (tgt_dev->dev == dev);
-+ goto out;
-+ }
-+ }
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+/* Returns 0 if the command processing should be continued, <0 otherwise */
-+static int scst_clear_task_set(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res;
-+ struct scst_device *dev = mcmd->mcmd_tgt_dev->dev;
-+ struct scst_tgt_dev *tgt_dev;
-+ LIST_HEAD(UA_tgt_devs);
-+
-+ TRACE_ENTRY();
-+
-+ TRACE(TRACE_MGMT, "Clearing task set (lun=%lld, mcmd=%p)",
-+ (long long unsigned int)mcmd->lun, mcmd);
-+
-+#if 0 /* we are SAM-3 */
-+ /*
-+ * When a logical unit is aborting one or more tasks from a SCSI
-+ * initiator port with the TASK ABORTED status it should complete all
-+ * of those tasks before entering additional tasks from that SCSI
-+ * initiator port into the task set - SAM2
-+ */
-+ mcmd->needs_unblocking = 1;
-+ spin_lock_bh(&dev->dev_lock);
-+ scst_block_dev(dev);
-+ spin_unlock_bh(&dev->dev_lock);
-+#endif
-+
-+ __scst_abort_task_set(mcmd, mcmd->mcmd_tgt_dev);
-+
-+ mutex_lock(&scst_mutex);
-+
-+ list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ struct scst_session *sess = tgt_dev->sess;
-+ struct scst_cmd *cmd;
-+ int aborted = 0;
-+
-+ if (tgt_dev == mcmd->mcmd_tgt_dev)
-+ continue;
-+
-+ spin_lock_irq(&sess->sess_list_lock);
-+
-+ TRACE_DBG("Searching in sess cmd list (sess=%p)", sess);
-+ list_for_each_entry(cmd, &sess->sess_cmd_list,
-+ sess_cmd_list_entry) {
-+ if ((cmd->dev == dev) ||
-+ ((cmd->dev == NULL) &&
-+ scst_is_cmd_belongs_to_dev(cmd, dev))) {
-+ scst_abort_cmd(cmd, mcmd, 1, 0);
-+ aborted = 1;
-+ }
-+ }
-+ spin_unlock_irq(&sess->sess_list_lock);
-+
-+ if (aborted)
-+ list_add_tail(&tgt_dev->extra_tgt_dev_list_entry,
-+ &UA_tgt_devs);
-+ }
-+
-+ tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev->dev, "CLEAR TASK SET", 0);
-+
-+ scst_unblock_aborted_cmds(1);
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ if (!dev->tas) {
-+ uint8_t sense_buffer[SCST_STANDARD_SENSE_LEN];
-+ int sl;
-+
-+ sl = scst_set_sense(sense_buffer, sizeof(sense_buffer),
-+ dev->d_sense,
-+ SCST_LOAD_SENSE(scst_sense_cleared_by_another_ini_UA));
-+
-+ list_for_each_entry(tgt_dev, &UA_tgt_devs,
-+ extra_tgt_dev_list_entry) {
-+ scst_check_set_UA(tgt_dev, sense_buffer, sl, 0);
-+ }
-+ }
-+
-+ scst_call_dev_task_mgmt_fn(mcmd, mcmd->mcmd_tgt_dev, 0);
-+
-+ res = scst_set_mcmd_next_state(mcmd);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/* Returns 0 if the command processing should be continued,
-+ * >0, if it should be requeued, <0 otherwise */
-+static int scst_mgmt_cmd_init(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res = 0, rc;
-+
-+ TRACE_ENTRY();
-+
-+ switch (mcmd->fn) {
-+ case SCST_ABORT_TASK:
-+ {
-+ struct scst_session *sess = mcmd->sess;
-+ struct scst_cmd *cmd;
-+
-+ spin_lock_irq(&sess->sess_list_lock);
-+ cmd = __scst_find_cmd_by_tag(sess, mcmd->tag, true);
-+ if (cmd == NULL) {
-+ TRACE_MGMT_DBG("ABORT TASK: command "
-+ "for tag %llu not found",
-+ (long long unsigned int)mcmd->tag);
-+ mcmd->status = SCST_MGMT_STATUS_TASK_NOT_EXIST;
-+ spin_unlock_irq(&sess->sess_list_lock);
-+ res = scst_set_mcmd_next_state(mcmd);
-+ goto out;
-+ }
-+ __scst_cmd_get(cmd);
-+ spin_unlock_irq(&sess->sess_list_lock);
-+ TRACE_DBG("Cmd to abort %p for tag %llu found",
-+ cmd, (long long unsigned int)mcmd->tag);
-+ mcmd->cmd_to_abort = cmd;
-+ mcmd->state = SCST_MCMD_STATE_EXEC;
-+ break;
-+ }
-+
-+ case SCST_TARGET_RESET:
-+ case SCST_NEXUS_LOSS_SESS:
-+ case SCST_ABORT_ALL_TASKS_SESS:
-+ case SCST_NEXUS_LOSS:
-+ case SCST_ABORT_ALL_TASKS:
-+ case SCST_UNREG_SESS_TM:
-+ mcmd->state = SCST_MCMD_STATE_EXEC;
-+ break;
-+
-+ case SCST_ABORT_TASK_SET:
-+ case SCST_CLEAR_ACA:
-+ case SCST_CLEAR_TASK_SET:
-+ case SCST_LUN_RESET:
-+ case SCST_PR_ABORT_ALL:
-+ rc = scst_mgmt_translate_lun(mcmd);
-+ if (rc == 0)
-+ mcmd->state = SCST_MCMD_STATE_EXEC;
-+ else if (rc < 0) {
-+ PRINT_ERROR("Corresponding device for LUN %lld not "
-+ "found", (long long unsigned int)mcmd->lun);
-+ mcmd->status = SCST_MGMT_STATUS_LUN_NOT_EXIST;
-+ res = scst_set_mcmd_next_state(mcmd);
-+ } else
-+ res = rc;
-+ break;
-+
-+ default:
-+ BUG();
-+ }
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/* Returns 0 if the command processing should be continued, <0 otherwise */
-+static int scst_target_reset(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res, rc;
-+ struct scst_device *dev;
-+ struct scst_acg *acg = mcmd->sess->acg;
-+ struct scst_acg_dev *acg_dev;
-+ int cont, c;
-+ LIST_HEAD(host_devs);
-+
-+ TRACE_ENTRY();
-+
-+ TRACE(TRACE_MGMT, "Target reset (mcmd %p, cmd count %d)",
-+ mcmd, atomic_read(&mcmd->sess->sess_cmd_count));
-+
-+ mcmd->needs_unblocking = 1;
-+
-+ mutex_lock(&scst_mutex);
-+
-+ list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) {
-+ struct scst_device *d;
-+ struct scst_tgt_dev *tgt_dev;
-+ int found = 0;
-+
-+ dev = acg_dev->dev;
-+
-+ spin_lock_bh(&dev->dev_lock);
-+ scst_block_dev(dev);
-+ scst_process_reset(dev, mcmd->sess, NULL, mcmd, true);
-+ spin_unlock_bh(&dev->dev_lock);
-+
-+ cont = 0;
-+ c = 0;
-+ list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
-+ dev_tgt_dev_list_entry) {
-+ cont = 1;
-+ if (mcmd->sess == tgt_dev->sess) {
-+ rc = scst_call_dev_task_mgmt_fn(mcmd,
-+ tgt_dev, 0);
-+ if (rc == SCST_DEV_TM_NOT_COMPLETED)
-+ c = 1;
-+ else if ((rc < 0) &&
-+ (mcmd->status == SCST_MGMT_STATUS_SUCCESS))
-+ mcmd->status = rc;
-+ break;
-+ }
-+ }
-+ if (cont && !c)
-+ continue;
-+
-+ if (dev->scsi_dev == NULL)
-+ continue;
-+
-+ list_for_each_entry(d, &host_devs, tm_dev_list_entry) {
-+ if (dev->scsi_dev->host->host_no ==
-+ d->scsi_dev->host->host_no) {
-+ found = 1;
-+ break;
-+ }
-+ }
-+ if (!found)
-+ list_add_tail(&dev->tm_dev_list_entry, &host_devs);
-+
-+ tm_dbg_task_mgmt(dev, "TARGET RESET", 0);
-+ }
-+
-+ scst_unblock_aborted_cmds(1);
-+
-+ /*
-+ * We suppose here that for all commands that already on devices
-+ * on/after scsi_reset_provider() completion callbacks will be called.
-+ */
-+
-+ list_for_each_entry(dev, &host_devs, tm_dev_list_entry) {
-+ /* dev->scsi_dev must be non-NULL here */
-+ TRACE(TRACE_MGMT, "Resetting host %d bus ",
-+ dev->scsi_dev->host->host_no);
-+ rc = scsi_reset_provider(dev->scsi_dev, SCSI_TRY_RESET_TARGET);
-+ TRACE(TRACE_MGMT, "Result of host %d target reset: %s",
-+ dev->scsi_dev->host->host_no,
-+ (rc == SUCCESS) ? "SUCCESS" : "FAILED");
-+#if 0
-+ if ((rc != SUCCESS) &&
-+ (mcmd->status == SCST_MGMT_STATUS_SUCCESS)) {
-+ /*
-+ * SCSI_TRY_RESET_BUS is also done by
-+ * scsi_reset_provider()
-+ */
-+ mcmd->status = SCST_MGMT_STATUS_FAILED;
-+ }
-+#else
-+ /*
-+ * scsi_reset_provider() returns very weird status, so let's
-+ * always succeed
-+ */
-+#endif
-+ }
-+
-+ list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) {
-+ dev = acg_dev->dev;
-+ if (dev->scsi_dev != NULL)
-+ dev->scsi_dev->was_reset = 0;
-+ }
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ res = scst_set_mcmd_next_state(mcmd);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/* Returns 0 if the command processing should be continued, <0 otherwise */
-+static int scst_lun_reset(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res, rc;
-+ struct scst_tgt_dev *tgt_dev = mcmd->mcmd_tgt_dev;
-+ struct scst_device *dev = tgt_dev->dev;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE(TRACE_MGMT, "Resetting LUN %lld (mcmd %p)",
-+ (long long unsigned int)tgt_dev->lun, mcmd);
-+
-+ mcmd->needs_unblocking = 1;
-+
-+ spin_lock_bh(&dev->dev_lock);
-+ scst_block_dev(dev);
-+ scst_process_reset(dev, mcmd->sess, NULL, mcmd, true);
-+ spin_unlock_bh(&dev->dev_lock);
-+
-+ rc = scst_call_dev_task_mgmt_fn(mcmd, tgt_dev, 1);
-+ if (rc != SCST_DEV_TM_NOT_COMPLETED)
-+ goto out_tm_dbg;
-+
-+ if (dev->scsi_dev != NULL) {
-+ TRACE(TRACE_MGMT, "Resetting host %d bus ",
-+ dev->scsi_dev->host->host_no);
-+ rc = scsi_reset_provider(dev->scsi_dev, SCSI_TRY_RESET_DEVICE);
-+#if 0
-+ if (rc != SUCCESS && mcmd->status == SCST_MGMT_STATUS_SUCCESS)
-+ mcmd->status = SCST_MGMT_STATUS_FAILED;
-+#else
-+ /*
-+ * scsi_reset_provider() returns very weird status, so let's
-+ * always succeed
-+ */
-+#endif
-+ dev->scsi_dev->was_reset = 0;
-+ }
-+
-+ scst_unblock_aborted_cmds(0);
-+
-+out_tm_dbg:
-+ tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev->dev, "LUN RESET", 0);
-+
-+ res = scst_set_mcmd_next_state(mcmd);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/* scst_mutex supposed to be held */
-+static void scst_do_nexus_loss_sess(struct scst_mgmt_cmd *mcmd)
-+{
-+ int i;
-+ struct scst_session *sess = mcmd->sess;
-+ struct scst_tgt_dev *tgt_dev;
-+
-+ TRACE_ENTRY();
-+
-+ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
-+ struct list_head *head = &sess->sess_tgt_dev_list[i];
-+ list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
-+ scst_nexus_loss(tgt_dev,
-+ (mcmd->fn != SCST_UNREG_SESS_TM));
-+ }
-+ }
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/* Returns 0 if the command processing should be continued, <0 otherwise */
-+static int scst_abort_all_nexus_loss_sess(struct scst_mgmt_cmd *mcmd,
-+ int nexus_loss)
-+{
-+ int res;
-+ int i;
-+ struct scst_session *sess = mcmd->sess;
-+ struct scst_tgt_dev *tgt_dev;
-+
-+ TRACE_ENTRY();
-+
-+ if (nexus_loss) {
-+ TRACE_MGMT_DBG("Nexus loss for sess %p (mcmd %p)",
-+ sess, mcmd);
-+ } else {
-+ TRACE_MGMT_DBG("Aborting all from sess %p (mcmd %p)",
-+ sess, mcmd);
-+ }
-+
-+ mutex_lock(&scst_mutex);
-+
-+ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
-+ struct list_head *head = &sess->sess_tgt_dev_list[i];
-+ list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
-+ int rc;
-+
-+ __scst_abort_task_set(mcmd, tgt_dev);
-+
-+ rc = scst_call_dev_task_mgmt_fn(mcmd, tgt_dev, 0);
-+ if (rc < 0 && mcmd->status == SCST_MGMT_STATUS_SUCCESS)
-+ mcmd->status = rc;
-+
-+ tm_dbg_task_mgmt(tgt_dev->dev, "NEXUS LOSS SESS or "
-+ "ABORT ALL SESS or UNREG SESS",
-+ (mcmd->fn == SCST_UNREG_SESS_TM));
-+ }
-+ }
-+
-+ scst_unblock_aborted_cmds(1);
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ res = scst_set_mcmd_next_state(mcmd);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/* scst_mutex supposed to be held */
-+static void scst_do_nexus_loss_tgt(struct scst_mgmt_cmd *mcmd)
-+{
-+ int i;
-+ struct scst_tgt *tgt = mcmd->sess->tgt;
-+ struct scst_session *sess;
-+
-+ TRACE_ENTRY();
-+
-+ list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) {
-+ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
-+ struct list_head *head = &sess->sess_tgt_dev_list[i];
-+ struct scst_tgt_dev *tgt_dev;
-+ list_for_each_entry(tgt_dev, head,
-+ sess_tgt_dev_list_entry) {
-+ scst_nexus_loss(tgt_dev, true);
-+ }
-+ }
-+ }
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+static int scst_abort_all_nexus_loss_tgt(struct scst_mgmt_cmd *mcmd,
-+ int nexus_loss)
-+{
-+ int res;
-+ int i;
-+ struct scst_tgt *tgt = mcmd->sess->tgt;
-+ struct scst_session *sess;
-+
-+ TRACE_ENTRY();
-+
-+ if (nexus_loss) {
-+ TRACE_MGMT_DBG("I_T Nexus loss (tgt %p, mcmd %p)",
-+ tgt, mcmd);
-+ } else {
-+ TRACE_MGMT_DBG("Aborting all from tgt %p (mcmd %p)",
-+ tgt, mcmd);
-+ }
-+
-+ mutex_lock(&scst_mutex);
-+
-+ list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) {
-+ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
-+ struct list_head *head = &sess->sess_tgt_dev_list[i];
-+ struct scst_tgt_dev *tgt_dev;
-+ list_for_each_entry(tgt_dev, head,
-+ sess_tgt_dev_list_entry) {
-+ int rc;
-+
-+ __scst_abort_task_set(mcmd, tgt_dev);
-+
-+ if (mcmd->sess == tgt_dev->sess) {
-+ rc = scst_call_dev_task_mgmt_fn(
-+ mcmd, tgt_dev, 0);
-+ if ((rc < 0) &&
-+ (mcmd->status == SCST_MGMT_STATUS_SUCCESS))
-+ mcmd->status = rc;
-+ }
-+
-+ tm_dbg_task_mgmt(tgt_dev->dev, "NEXUS LOSS or "
-+ "ABORT ALL", 0);
-+ }
-+ }
-+ }
-+
-+ scst_unblock_aborted_cmds(1);
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ res = scst_set_mcmd_next_state(mcmd);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static int scst_abort_task(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res;
-+ struct scst_cmd *cmd = mcmd->cmd_to_abort;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_MGMT_DBG("Aborting task (cmd %p, sn %d, set %d, tag %llu, "
-+ "queue_type %x)", cmd, cmd->sn, cmd->sn_set,
-+ (long long unsigned int)mcmd->tag, cmd->queue_type);
-+
-+ if (mcmd->lun_set && (mcmd->lun != cmd->lun)) {
-+ PRINT_ERROR("ABORT TASK: LUN mismatch: mcmd LUN %llx, "
-+ "cmd LUN %llx, cmd tag %llu",
-+ (long long unsigned int)mcmd->lun,
-+ (long long unsigned int)cmd->lun,
-+ (long long unsigned int)mcmd->tag);
-+ mcmd->status = SCST_MGMT_STATUS_REJECTED;
-+ } else if (mcmd->cmd_sn_set &&
-+ (scst_sn_before(mcmd->cmd_sn, cmd->tgt_sn) ||
-+ (mcmd->cmd_sn == cmd->tgt_sn))) {
-+ PRINT_ERROR("ABORT TASK: SN mismatch: mcmd SN %x, "
-+ "cmd SN %x, cmd tag %llu", mcmd->cmd_sn,
-+ cmd->tgt_sn, (long long unsigned int)mcmd->tag);
-+ mcmd->status = SCST_MGMT_STATUS_REJECTED;
-+ } else {
-+ spin_lock_irq(&cmd->sess->sess_list_lock);
-+ scst_abort_cmd(cmd, mcmd, 0, 1);
-+ spin_unlock_irq(&cmd->sess->sess_list_lock);
-+
-+ scst_unblock_aborted_cmds(0);
-+ }
-+
-+ res = scst_set_mcmd_next_state(mcmd);
-+
-+ mcmd->cmd_to_abort = NULL; /* just in case */
-+
-+ __scst_cmd_put(cmd);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+/* Returns 0 if the command processing should be continued, <0 otherwise */
-+static int scst_mgmt_cmd_exec(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res = 0;
-+
-+ TRACE_ENTRY();
-+
-+ mcmd->status = SCST_MGMT_STATUS_SUCCESS;
-+
-+ switch (mcmd->fn) {
-+ case SCST_ABORT_TASK:
-+ res = scst_abort_task(mcmd);
-+ break;
-+
-+ case SCST_ABORT_TASK_SET:
-+ case SCST_PR_ABORT_ALL:
-+ res = scst_abort_task_set(mcmd);
-+ break;
-+
-+ case SCST_CLEAR_TASK_SET:
-+ if (mcmd->mcmd_tgt_dev->dev->tst ==
-+ SCST_CONTR_MODE_SEP_TASK_SETS)
-+ res = scst_abort_task_set(mcmd);
-+ else
-+ res = scst_clear_task_set(mcmd);
-+ break;
-+
-+ case SCST_LUN_RESET:
-+ res = scst_lun_reset(mcmd);
-+ break;
-+
-+ case SCST_TARGET_RESET:
-+ res = scst_target_reset(mcmd);
-+ break;
-+
-+ case SCST_ABORT_ALL_TASKS_SESS:
-+ res = scst_abort_all_nexus_loss_sess(mcmd, 0);
-+ break;
-+
-+ case SCST_NEXUS_LOSS_SESS:
-+ case SCST_UNREG_SESS_TM:
-+ res = scst_abort_all_nexus_loss_sess(mcmd, 1);
-+ break;
-+
-+ case SCST_ABORT_ALL_TASKS:
-+ res = scst_abort_all_nexus_loss_tgt(mcmd, 0);
-+ break;
-+
-+ case SCST_NEXUS_LOSS:
-+ res = scst_abort_all_nexus_loss_tgt(mcmd, 1);
-+ break;
-+
-+ case SCST_CLEAR_ACA:
-+ if (scst_call_dev_task_mgmt_fn(mcmd, mcmd->mcmd_tgt_dev, 1) ==
-+ SCST_DEV_TM_NOT_COMPLETED) {
-+ mcmd->status = SCST_MGMT_STATUS_FN_NOT_SUPPORTED;
-+ /* Nothing to do (yet) */
-+ }
-+ goto out_done;
-+
-+ default:
-+ PRINT_ERROR("Unknown task management function %d", mcmd->fn);
-+ mcmd->status = SCST_MGMT_STATUS_REJECTED;
-+ goto out_done;
-+ }
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_done:
-+ res = scst_set_mcmd_next_state(mcmd);
-+ goto out;
-+}
-+
-+static void scst_call_task_mgmt_affected_cmds_done(struct scst_mgmt_cmd *mcmd)
-+{
-+ struct scst_session *sess = mcmd->sess;
-+
-+ if ((sess->tgt->tgtt->task_mgmt_affected_cmds_done != NULL) &&
-+ (mcmd->fn != SCST_UNREG_SESS_TM) &&
-+ (mcmd->fn != SCST_PR_ABORT_ALL)) {
-+ TRACE_DBG("Calling target %s task_mgmt_affected_cmds_done(%p)",
-+ sess->tgt->tgtt->name, sess);
-+ sess->tgt->tgtt->task_mgmt_affected_cmds_done(mcmd);
-+ TRACE_MGMT_DBG("Target's %s task_mgmt_affected_cmds_done() "
-+ "returned", sess->tgt->tgtt->name);
-+ }
-+ return;
-+}
-+
-+static int scst_mgmt_affected_cmds_done(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res;
-+
-+ TRACE_ENTRY();
-+
-+ mutex_lock(&scst_mutex);
-+
-+ switch (mcmd->fn) {
-+ case SCST_NEXUS_LOSS_SESS:
-+ case SCST_UNREG_SESS_TM:
-+ scst_do_nexus_loss_sess(mcmd);
-+ break;
-+
-+ case SCST_NEXUS_LOSS:
-+ scst_do_nexus_loss_tgt(mcmd);
-+ break;
-+ }
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ scst_call_task_mgmt_affected_cmds_done(mcmd);
-+
-+ res = scst_set_mcmd_next_state(mcmd);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static void scst_mgmt_cmd_send_done(struct scst_mgmt_cmd *mcmd)
-+{
-+ struct scst_device *dev;
-+ struct scst_session *sess = mcmd->sess;
-+
-+ TRACE_ENTRY();
-+
-+ mcmd->state = SCST_MCMD_STATE_FINISHED;
-+ if (scst_is_strict_mgmt_fn(mcmd->fn) && (mcmd->completed_cmd_count > 0))
-+ mcmd->status = SCST_MGMT_STATUS_TASK_NOT_EXIST;
-+
-+ if (mcmd->fn < SCST_UNREG_SESS_TM)
-+ TRACE(TRACE_MGMT, "TM fn %d (%p) finished, "
-+ "status %d", mcmd->fn, mcmd, mcmd->status);
-+ else
-+ TRACE_MGMT_DBG("TM fn %d (%p) finished, "
-+ "status %d", mcmd->fn, mcmd, mcmd->status);
-+
-+ if (mcmd->fn == SCST_PR_ABORT_ALL) {
-+ mcmd->origin_pr_cmd->scst_cmd_done(mcmd->origin_pr_cmd,
-+ SCST_CMD_STATE_DEFAULT,
-+ SCST_CONTEXT_THREAD);
-+ } else if ((sess->tgt->tgtt->task_mgmt_fn_done != NULL) &&
-+ (mcmd->fn != SCST_UNREG_SESS_TM)) {
-+ TRACE_DBG("Calling target %s task_mgmt_fn_done(%p)",
-+ sess->tgt->tgtt->name, sess);
-+ sess->tgt->tgtt->task_mgmt_fn_done(mcmd);
-+ TRACE_MGMT_DBG("Target's %s task_mgmt_fn_done() "
-+ "returned", sess->tgt->tgtt->name);
-+ }
-+
-+ if (mcmd->needs_unblocking) {
-+ switch (mcmd->fn) {
-+ case SCST_LUN_RESET:
-+ case SCST_CLEAR_TASK_SET:
-+ dev = mcmd->mcmd_tgt_dev->dev;
-+ spin_lock_bh(&dev->dev_lock);
-+ scst_unblock_dev(dev);
-+ spin_unlock_bh(&dev->dev_lock);
-+ break;
-+
-+ case SCST_TARGET_RESET:
-+ {
-+ struct scst_acg *acg = mcmd->sess->acg;
-+ struct scst_acg_dev *acg_dev;
-+
-+ mutex_lock(&scst_mutex);
-+ list_for_each_entry(acg_dev, &acg->acg_dev_list,
-+ acg_dev_list_entry) {
-+ dev = acg_dev->dev;
-+ spin_lock_bh(&dev->dev_lock);
-+ scst_unblock_dev(dev);
-+ spin_unlock_bh(&dev->dev_lock);
-+ }
-+ mutex_unlock(&scst_mutex);
-+ break;
-+ }
-+
-+ default:
-+ BUG();
-+ break;
-+ }
-+ }
-+
-+ mcmd->tgt_priv = NULL;
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+
-+/* Returns >0, if cmd should be requeued */
-+static int scst_process_mgmt_cmd(struct scst_mgmt_cmd *mcmd)
-+{
-+ int res = 0;
-+
-+ TRACE_ENTRY();
-+
-+ /*
-+ * We are in the TM thread and mcmd->state guaranteed to not be
-+ * changed behind us.
-+ */
-+
-+ TRACE_DBG("mcmd %p, state %d", mcmd, mcmd->state);
-+
-+ while (1) {
-+ switch (mcmd->state) {
-+ case SCST_MCMD_STATE_INIT:
-+ res = scst_mgmt_cmd_init(mcmd);
-+ if (res != 0)
-+ goto out;
-+ break;
-+
-+ case SCST_MCMD_STATE_EXEC:
-+ if (scst_mgmt_cmd_exec(mcmd))
-+ goto out;
-+ break;
-+
-+ case SCST_MCMD_STATE_AFFECTED_CMDS_DONE:
-+ if (scst_mgmt_affected_cmds_done(mcmd))
-+ goto out;
-+ break;
-+
-+ case SCST_MCMD_STATE_DONE:
-+ scst_mgmt_cmd_send_done(mcmd);
-+ break;
-+
-+ case SCST_MCMD_STATE_FINISHED:
-+ scst_free_mgmt_cmd(mcmd);
-+ /* mcmd is dead */
-+ goto out;
-+
-+ default:
-+ PRINT_CRIT_ERROR("Wrong mcmd %p state %d (fn %d, "
-+ "cmd_finish_wait_count %d, cmd_done_wait_count "
-+ "%d)", mcmd, mcmd->state, mcmd->fn,
-+ mcmd->cmd_finish_wait_count,
-+ mcmd->cmd_done_wait_count);
-+ BUG();
-+ res = -1;
-+ goto out;
-+ }
-+ }
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+
-+static inline int test_mgmt_cmd_list(void)
-+{
-+ int res = !list_empty(&scst_active_mgmt_cmd_list) ||
-+ unlikely(kthread_should_stop());
-+ return res;
-+}
-+
-+int scst_tm_thread(void *arg)
-+{
-+ TRACE_ENTRY();
-+
-+ PRINT_INFO("Task management thread started, PID %d", current->pid);
-+
-+ current->flags |= PF_NOFREEZE;
-+
-+ set_user_nice(current, -10);
-+
-+ spin_lock_irq(&scst_mcmd_lock);
-+ while (!kthread_should_stop()) {
-+ wait_queue_t wait;
-+ init_waitqueue_entry(&wait, current);
-+
-+ if (!test_mgmt_cmd_list()) {
-+ add_wait_queue_exclusive(&scst_mgmt_cmd_list_waitQ,
-+ &wait);
-+ for (;;) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (test_mgmt_cmd_list())
-+ break;
-+ spin_unlock_irq(&scst_mcmd_lock);
-+ schedule();
-+ spin_lock_irq(&scst_mcmd_lock);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&scst_mgmt_cmd_list_waitQ, &wait);
-+ }
-+
-+ while (!list_empty(&scst_active_mgmt_cmd_list)) {
-+ int rc;
-+ struct scst_mgmt_cmd *mcmd;
-+ mcmd = list_entry(scst_active_mgmt_cmd_list.next,
-+ typeof(*mcmd), mgmt_cmd_list_entry);
-+ TRACE_MGMT_DBG("Deleting mgmt cmd %p from active cmd "
-+ "list", mcmd);
-+ list_del(&mcmd->mgmt_cmd_list_entry);
-+ spin_unlock_irq(&scst_mcmd_lock);
-+ rc = scst_process_mgmt_cmd(mcmd);
-+ spin_lock_irq(&scst_mcmd_lock);
-+ if (rc > 0) {
-+ if (test_bit(SCST_FLAG_SUSPENDED, &scst_flags) &&
-+ !test_bit(SCST_FLAG_SUSPENDING,
-+ &scst_flags)) {
-+ TRACE_MGMT_DBG("Adding mgmt cmd %p to "
-+ "head of delayed mgmt cmd list",
-+ mcmd);
-+ list_add(&mcmd->mgmt_cmd_list_entry,
-+ &scst_delayed_mgmt_cmd_list);
-+ } else {
-+ TRACE_MGMT_DBG("Adding mgmt cmd %p to "
-+ "head of active mgmt cmd list",
-+ mcmd);
-+ list_add(&mcmd->mgmt_cmd_list_entry,
-+ &scst_active_mgmt_cmd_list);
-+ }
-+ }
-+ }
-+ }
-+ spin_unlock_irq(&scst_mcmd_lock);
-+
-+ /*
-+ * If kthread_should_stop() is true, we are guaranteed to be
-+ * on the module unload, so scst_active_mgmt_cmd_list must be empty.
-+ */
-+ BUG_ON(!list_empty(&scst_active_mgmt_cmd_list));
-+
-+ PRINT_INFO("Task management thread PID %d finished", current->pid);
-+
-+ TRACE_EXIT();
-+ return 0;
-+}
-+
-+static struct scst_mgmt_cmd *scst_pre_rx_mgmt_cmd(struct scst_session
-+ *sess, int fn, int atomic, void *tgt_priv)
-+{
-+ struct scst_mgmt_cmd *mcmd = NULL;
-+
-+ TRACE_ENTRY();
-+
-+ if (unlikely(sess->tgt->tgtt->task_mgmt_fn_done == NULL)) {
-+ PRINT_ERROR("New mgmt cmd, but task_mgmt_fn_done() is NULL "
-+ "(target %s)", sess->tgt->tgtt->name);
-+ goto out;
-+ }
-+
-+ mcmd = scst_alloc_mgmt_cmd(atomic ? GFP_ATOMIC : GFP_KERNEL);
-+ if (mcmd == NULL) {
-+ PRINT_CRIT_ERROR("Lost TM fn %d, initiator %s", fn,
-+ sess->initiator_name);
-+ goto out;
-+ }
-+
-+ mcmd->sess = sess;
-+ mcmd->fn = fn;
-+ mcmd->state = SCST_MCMD_STATE_INIT;
-+ mcmd->tgt_priv = tgt_priv;
-+
-+ if (fn == SCST_PR_ABORT_ALL) {
-+ atomic_inc(&mcmd->origin_pr_cmd->pr_abort_counter->pr_abort_pending_cnt);
-+ atomic_inc(&mcmd->origin_pr_cmd->pr_abort_counter->pr_aborting_cnt);
-+ }
-+
-+out:
-+ TRACE_EXIT();
-+ return mcmd;
-+}
-+
-+static int scst_post_rx_mgmt_cmd(struct scst_session *sess,
-+ struct scst_mgmt_cmd *mcmd)
-+{
-+ unsigned long flags;
-+ int res = 0;
-+
-+ TRACE_ENTRY();
-+
-+ scst_sess_get(sess);
-+
-+ if (unlikely(sess->shut_phase != SCST_SESS_SPH_READY)) {
-+ PRINT_CRIT_ERROR("New mgmt cmd while shutting down the "
-+ "session %p shut_phase %ld", sess, sess->shut_phase);
-+ BUG();
-+ }
-+
-+ local_irq_save(flags);
-+
-+ spin_lock(&sess->sess_list_lock);
-+ atomic_inc(&sess->sess_cmd_count);
-+
-+ if (unlikely(sess->init_phase != SCST_SESS_IPH_READY)) {
-+ switch (sess->init_phase) {
-+ case SCST_SESS_IPH_INITING:
-+ TRACE_DBG("Adding mcmd %p to init deferred mcmd list",
-+ mcmd);
-+ list_add_tail(&mcmd->mgmt_cmd_list_entry,
-+ &sess->init_deferred_mcmd_list);
-+ goto out_unlock;
-+ case SCST_SESS_IPH_SUCCESS:
-+ break;
-+ case SCST_SESS_IPH_FAILED:
-+ res = -1;
-+ goto out_unlock;
-+ default:
-+ BUG();
-+ }
-+ }
-+
-+ spin_unlock(&sess->sess_list_lock);
-+
-+ TRACE_MGMT_DBG("Adding mgmt cmd %p to active mgmt cmd list", mcmd);
-+ spin_lock(&scst_mcmd_lock);
-+ list_add_tail(&mcmd->mgmt_cmd_list_entry, &scst_active_mgmt_cmd_list);
-+ spin_unlock(&scst_mcmd_lock);
-+
-+ local_irq_restore(flags);
-+
-+ wake_up(&scst_mgmt_cmd_list_waitQ);
-+
-+out:
-+ TRACE_EXIT();
-+ return res;
-+
-+out_unlock:
-+ spin_unlock(&sess->sess_list_lock);
-+ local_irq_restore(flags);
-+ goto out;
-+}
-+
-+/**
-+ * scst_rx_mgmt_fn() - create new management command and send it for execution
-+ *
-+ * Description:
-+ * Creates new management command and sends it for execution.
-+ *
-+ * Returns 0 for success, error code otherwise.
-+ *
-+ * Must not be called in parallel with scst_unregister_session() for the
-+ * same sess.
-+ */
-+int scst_rx_mgmt_fn(struct scst_session *sess,
-+ const struct scst_rx_mgmt_params *params)
-+{
-+ int res = -EFAULT;
-+ struct scst_mgmt_cmd *mcmd = NULL;
-+
-+ TRACE_ENTRY();
-+
-+ switch (params->fn) {
-+ case SCST_ABORT_TASK:
-+ BUG_ON(!params->tag_set);
-+ break;
-+ case SCST_TARGET_RESET:
-+ case SCST_ABORT_ALL_TASKS:
-+ case SCST_NEXUS_LOSS:
-+ break;
-+ default:
-+ BUG_ON(!params->lun_set);
-+ }
-+
-+ mcmd = scst_pre_rx_mgmt_cmd(sess, params->fn, params->atomic,
-+ params->tgt_priv);
-+ if (mcmd == NULL)
-+ goto out;
-+
-+ if (params->lun_set) {
-+ mcmd->lun = scst_unpack_lun(params->lun, params->lun_len);
-+ if (mcmd->lun == NO_SUCH_LUN)
-+ goto out_free;
-+ mcmd->lun_set = 1;
-+ }
-+
-+ if (params->tag_set)
-+ mcmd->tag = params->tag;
-+
-+ mcmd->cmd_sn_set = params->cmd_sn_set;
-+ mcmd->cmd_sn = params->cmd_sn;
-+
-+ if (params->fn < SCST_UNREG_SESS_TM)
-+ TRACE(TRACE_MGMT, "TM fn %d (%p)", params->fn, mcmd);
-+ else
-+ TRACE_MGMT_DBG("TM fn %d (%p)", params->fn, mcmd);
-+
-+ TRACE_MGMT_DBG("sess=%p, tag_set %d, tag %lld, lun_set %d, "
-+ "lun=%lld, cmd_sn_set %d, cmd_sn %d, priv %p", sess,
-+ params->tag_set,
-+ (long long unsigned int)params->tag,
-+ params->lun_set,
-+ (long long unsigned int)mcmd->lun,
-+ params->cmd_sn_set,
-+ params->cmd_sn,
-+ params->tgt_priv);
-+
-+ if (scst_post_rx_mgmt_cmd(sess, mcmd) != 0)
-+ goto out_free;
-+
-+ res = 0;
-+
-+out:
-+ TRACE_EXIT_RES(res);
-+ return res;
-+
-+out_free:
-+ scst_free_mgmt_cmd(mcmd);
-+ mcmd = NULL;
-+ goto out;
-+}
-+EXPORT_SYMBOL(scst_rx_mgmt_fn);
-+
-+/*
-+ * Written by Jack Handy - jakkhandy@hotmail.com
-+ * Taken by Gennadiy Nerubayev <parakie@gmail.com> from
-+ * http://www.codeproject.com/KB/string/wildcmp.aspx. No license attached
-+ * to it, and it's posted on a free site; assumed to be free for use.
-+ *
-+ * Added the negative sign support - VLNB
-+ *
-+ * Also see comment for wildcmp().
-+ *
-+ * User space part of iSCSI-SCST also has a copy of this code, so fixing a bug
-+ * here, don't forget to fix the copy too!
-+ */
-+static bool __wildcmp(const char *wild, const char *string, int recursion_level)
-+{
-+ const char *cp = NULL, *mp = NULL;
-+
-+ while ((*string) && (*wild != '*')) {
-+ if ((*wild == '!') && (recursion_level == 0))
-+ return !__wildcmp(++wild, string, ++recursion_level);
-+
-+ if ((*wild != *string) && (*wild != '?'))
-+ return false;
-+
-+ wild++;
-+ string++;
-+ }
-+
-+ while (*string) {
-+ if ((*wild == '!') && (recursion_level == 0))
-+ return !__wildcmp(++wild, string, ++recursion_level);
-+
-+ if (*wild == '*') {
-+ if (!*++wild)
-+ return true;
-+
-+ mp = wild;
-+ cp = string+1;
-+ } else if ((*wild == *string) || (*wild == '?')) {
-+ wild++;
-+ string++;
-+ } else {
-+ wild = mp;
-+ string = cp++;
-+ }
-+ }
-+
-+ while (*wild == '*')
-+ wild++;
-+
-+ return !*wild;
-+}
-+
-+/*
-+ * Returns true if string "string" matches pattern "wild", false otherwise.
-+ * Pattern is a regular DOS-type pattern, containing '*' and '?' symbols.
-+ * '*' means match all any symbols, '?' means match only any single symbol.
-+ *
-+ * For instance:
-+ * if (wildcmp("bl?h.*", "blah.jpg")) {
-+ * // match
-+ * } else {
-+ * // no match
-+ * }
-+ *
-+ * Also it supports boolean inversion sign '!', which does boolean inversion of
-+ * the value of the rest of the string. Only one '!' allowed in the pattern,
-+ * other '!' are treated as regular symbols. For instance:
-+ * if (wildcmp("bl!?h.*", "blah.jpg")) {
-+ * // no match
-+ * } else {
-+ * // match
-+ * }
-+ *
-+ * Also see comment for __wildcmp().
-+ */
-+static bool wildcmp(const char *wild, const char *string)
-+{
-+ return __wildcmp(wild, string, 0);
-+}
-+
-+/* scst_mutex supposed to be held */
-+static struct scst_acg *scst_find_tgt_acg_by_name_wild(struct scst_tgt *tgt,
-+ const char *initiator_name)
-+{
-+ struct scst_acg *acg, *res = NULL;
-+ struct scst_acn *n;
-+
-+ TRACE_ENTRY();
-+
-+ if (initiator_name == NULL)
-+ goto out;
-+
-+ list_for_each_entry(acg, &tgt->tgt_acg_list, acg_list_entry) {
-+ list_for_each_entry(n, &acg->acn_list, acn_list_entry) {
-+ if (wildcmp(n->name, initiator_name)) {
-+ TRACE_DBG("Access control group %s found",
-+ acg->acg_name);
-+ res = acg;
-+ goto out;
-+ }
-+ }
-+ }
-+
-+out:
-+ TRACE_EXIT_HRES(res);
-+ return res;
-+}
-+
-+/* Must be called under scst_mutex */
-+static struct scst_acg *__scst_find_acg(struct scst_tgt *tgt,
-+ const char *initiator_name)
-+{
-+ struct scst_acg *acg = NULL;
-+
-+ TRACE_ENTRY();
-+
-+ acg = scst_find_tgt_acg_by_name_wild(tgt, initiator_name);
-+ if (acg == NULL)
-+ acg = tgt->default_acg;
-+
-+ TRACE_EXIT_HRES((unsigned long)acg);
-+ return acg;
-+}
-+
-+/* Must be called under scst_mutex */
-+struct scst_acg *scst_find_acg(const struct scst_session *sess)
-+{
-+ return __scst_find_acg(sess->tgt, sess->initiator_name);
-+}
-+
-+/**
-+ * scst_initiator_has_luns() - check if this initiator will see any LUNs
-+ *
-+ * Checks if this initiator will see any LUNs upon connect to this target.
-+ * Returns true if yes and false otherwise.
-+ */
-+bool scst_initiator_has_luns(struct scst_tgt *tgt, const char *initiator_name)
-+{
-+ bool res;
-+ struct scst_acg *acg;
-+
-+ TRACE_ENTRY();
-+
-+ mutex_lock(&scst_mutex);
-+
-+ acg = __scst_find_acg(tgt, initiator_name);
-+
-+ res = !list_empty(&acg->acg_dev_list);
-+
-+ mutex_unlock(&scst_mutex);
-+
-+ TRACE_EXIT_RES(res);
-+ return res;
-+}
-+EXPORT_SYMBOL_GPL(scst_initiator_has_luns);
-+
-+static int scst_init_session(struct scst_session *sess)
-+{
-+ int res = 0;
-+ struct scst_cmd *cmd;
-+ struct scst_mgmt_cmd *mcmd, *tm;
-+ int mwake = 0;
-+
-+ TRACE_ENTRY();
-+
-+ mutex_lock(&scst_mutex);
-+
-+ sess->acg = scst_find_acg(sess);
-+
-+ PRINT_INFO("Using security group \"%s\" for initiator \"%s\" "
-+ "(target %s)", sess->acg->acg_name, sess->initiator_name,
-+ sess->tgt->tgt_name);
-+
-+ list_add_tail(&sess->acg_sess_list_entry, &sess->acg->acg_sess_list);
-+
-+ TRACE_DBG("Adding sess %p to tgt->sess_list", sess);
-+ list_add_tail(&sess->sess_list_entry, &sess->tgt->sess_list);
-+
-+ if (sess->tgt->tgtt->get_initiator_port_transport_id != NULL) {
-+ res = sess->tgt->tgtt->get_initiator_port_transport_id(
-+ sess->tgt, sess, &sess->transport_id);
-+ if (res != 0) {
-+ PRINT_ERROR("Unable to make initiator %s port "
-+ "transport id", sess->initiator_name);
-+ goto failed;
-+ }
-+ TRACE_PR("sess %p (ini %s), transport id %s/%d", sess,
-+ sess->initiator_name,
-+ debug_transport_id_to_initiator_name(
-+ sess->transport_id), sess->tgt->rel_tgt_id);
-+ }
-+
-+ res = scst_sess_sysfs_create(sess);
-+ if (res != 0)
-+ goto failed;
-+
-+ /*
-+ * scst_sess_alloc_tgt_devs() must be called after session added in the
-+ * sess_list to not race with scst_check_reassign_sess()!
-+ */
-+ res = scst_sess_alloc_tgt_devs(sess);
-+
-+failed:
-+ mutex_unlock(&scst_mutex);
-+
-+ if (sess->init_result_fn) {
-+ TRACE_DBG("Calling init_result_fn(%p)", sess);
-+ sess->init_result_fn(sess, sess->reg_sess_data, res);
-+ TRACE_DBG("%s", "init_result_fn() returned");
-+ }
-+
-+ spin_lock_irq(&sess->sess_list_lock);
-+
-+ if (res == 0)
-+ sess->init_phase = SCST_SESS_IPH_SUCCESS;
-+ else
-+ sess->init_phase = SCST_SESS_IPH_FAILED;
-+
-+restart:
-+ list_for_each_entry(cmd, &sess->init_deferred_cmd_list,
-+ cmd_list_entry) {
-+ TRACE_DBG("Deleting cmd %p from init deferred cmd list", cmd);
-+ list_del(&cmd->cmd_list_entry);
-+ atomic_dec(&sess->sess_cmd_count);
-+ spin_unlock_irq(&sess->sess_list_lock);
-+ scst_cmd_init_done(cmd, SCST_CONTEXT_THREAD);
-+ spin_lock_irq(&sess->sess_list_lock);
-+ goto restart;
-+ }
-+
-+ spin_lock(&scst_mcmd_lock);
-+ list_for_each_entry_safe(mcmd, tm, &sess->init_deferred_mcmd_list,
-+ mgmt_cmd_list_entry) {
-+ TRACE_DBG("Moving mgmt command %p from init deferred mcmd list",
-+ mcmd);
-+ list_move_tail(&mcmd->mgmt_cmd_list_entry,
-+ &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);
-+
-+ if (mwake)
-+ wake_up(&scst_mgmt_cmd_list_waitQ);
-+
-+ scst_sess_put(sess);
-+
-+ TRACE_EXIT();
-+ return res;
-+}
-+
-+/**
-+ * scst_register_session() - register session
-+ * @tgt: target
-+ * @atomic: true, if the function called in the atomic context. If false,
-+ * 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 the default
-+ * target's LUNs are used.
-+ * @tgt_priv: pointer to target driver's private data
-+ * @result_fn_data: any target driver supplied data
-+ * @result_fn: pointer to the function that will be asynchronously called
-+ * when session initialization finishes.
-+ * Can be NULL. Parameters:
-+ * - sess - session
-+ * - data - target driver supplied to scst_register_session()
-+ * data
-+ * - result - session initialization result, 0 on success or
-+ * appropriate error code otherwise
-+ *
-+ * Description:
-+ * Registers new session. Returns new session on success or NULL otherwise.
-+ *
-+ * Note: A session creation and initialization is a complex task,
-+ * which requires sleeping state, so it can't be fully done
-+ * in interrupt context. Therefore the "bottom half" of it, if
-+ * scst_register_session() is called from atomic context, will be
-+ * done in SCST thread context. In this case scst_register_session()
-+ * will return not completely initialized session, but the target
-+ * driver can supply commands to this session via scst_rx_cmd().
-+ * Those commands processing will be delayed inside SCST until
-+ * the session initialization is finished, then their processing
-+ * will be restarted. The target driver will be notified about
-+ * finish of the session initialization by function result_fn().
-+ * On success the target driver could do nothing, but if the
-+ * initialization fails, the target driver must ensure that
-+ * no more new commands being sent or will be sent to SCST after
-+ * result_fn() returns. All already sent to SCST commands for
-+ * failed session will be returned in xmit_response() with BUSY status.
-+ * In case of failure the driver shall call scst_unregister_session()
-+ * inside result_fn(), it will NOT be called automatically.
-+ */
-+struct scst_session *scst_register_session(struct scst_tgt *tgt, int atomic,
-+ const char *initiator_name, void *tgt_priv, void *result_fn_data,
-+ void (*result_fn) (struct scst_session *sess, void *data, int result))
-+{
-+ struct scst_session *sess;
-+ int res;
-+ unsigned long flags;
-+
-+ TRACE_ENTRY();
-+
-+ sess = scst_alloc_session(tgt, atomic ? GFP_ATOMIC : GFP_KERNEL,
-+ initiator_name);
-+ if (sess == NULL)
-+ goto out;
-+
-+ scst_sess_set_tgt_priv(sess, tgt_priv);
-+
-+ scst_sess_get(sess); /* one for registered session */
-+ scst_sess_get(sess); /* one held until sess is inited */
-+
-+ if (atomic) {
-+ sess->reg_sess_data = result_fn_data;
-+ sess->init_result_fn = result_fn;
-+ spin_lock_irqsave(&scst_mgmt_lock, flags);
-+ TRACE_DBG("Adding sess %p to scst_sess_init_list", sess);
-+ list_add_tail(&sess->sess_init_list_entry,
-+ &scst_sess_init_list);
-+ spin_unlock_irqrestore(&scst_mgmt_lock, flags);
-+ wake_up(&scst_mgmt_waitQ);
-+ } else {
-+ res = scst_init_session(sess);
-+ if (res != 0)
-+ goto out_free;
-+ }
-+
-+out:
-+ TRACE_EXIT();
-+ return sess;
-+
-+out_free:
-+ scst_free_session(sess);
-+ sess = NULL;
-+ goto out;
-+}
-+EXPORT_SYMBOL_GPL(scst_register_session);
-+
-+/**
-+ * scst_register_session_non_gpl() - register session (non-GPL version)
-+ * @tgt: target
-+ * @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 the default
-+ * target's LUNs are used.
-+ * @tgt_priv: pointer to target driver's private data
-+ *
-+ * Description:
-+ * Registers new session. Returns new session on success or NULL otherwise.
-+ */
-+struct scst_session *scst_register_session_non_gpl(struct scst_tgt *tgt,
-+ const char *initiator_name, void *tgt_priv)
-+{
-+ return scst_register_session(tgt, 0, initiator_name, tgt_priv,
-+ NULL, NULL);
-+}
-+EXPORT_SYMBOL(scst_register_session_non_gpl);
-+
-+/**
-+ * scst_unregister_session() - unregister session
-+ * @sess: session to be unregistered
-+ * @wait: if true, instructs to wait until all commands, which
-+ * currently is being executed and belonged to the session,
-+ * finished. Otherwise, target driver should be prepared to
-+ * receive xmit_response() for the session's command after
-+ * scst_unregister_session() returns.
-+ * @unreg_done_fn: pointer to the function that will be asynchronously called
-+ * when the last session's command finishes and
-+ * the session is about to be completely freed. Can be NULL.
-+ * Parameter:
-+ * - sess - session
-+ *
-+ * Unregisters session.
-+ *
-+ * Notes:
-+ * - All outstanding commands will be finished regularly. After
-+ * scst_unregister_session() returned, no new commands must be sent to
-+ * SCST via scst_rx_cmd().
-+ *
-+ * - The caller must ensure that no scst_rx_cmd() or scst_rx_mgmt_fn_*() is
-+ * called in parallel with scst_unregister_session().
-+ *
-+ * - Can be called before result_fn() of scst_register_session() called,
-+ * i.e. during the session registration/initialization.
-+ *
-+ * - It is highly recommended to call scst_unregister_session() as soon as it
-+ * gets clear that session will be unregistered and not to wait until all
-+ * related commands finished. This function provides the wait functionality,
-+ * but it also starts recovering stuck commands, if there are any.
-+ * Otherwise, your target driver could wait for those commands forever.
-+ */
-+void scst_unregister_session(struct scst_session *sess, int wait,
-+ void (*unreg_done_fn) (struct scst_session *sess))
-+{
-+ unsigned long flags;
-+ DECLARE_COMPLETION_ONSTACK(c);
-+ int rc, lun;
-+
-+ TRACE_ENTRY();
-+
-+ TRACE_MGMT_DBG("Unregistering session %p (wait %d)", sess, wait);
-+
-+ sess->unreg_done_fn = unreg_done_fn;
-+
-+ /* Abort all outstanding commands and clear reservation, if necessary */
-+ lun = 0;
-+ rc = scst_rx_mgmt_fn_lun(sess, SCST_UNREG_SESS_TM,
-+ (uint8_t *)&lun, sizeof(lun), SCST_ATOMIC, NULL);
-+ if (rc != 0) {
-+ PRINT_ERROR("SCST_UNREG_SESS_TM failed %d (sess %p)",
-+ rc, sess);
-+ }
-+
-+ sess->shut_phase = SCST_SESS_SPH_SHUTDOWN;
-+
-+ spin_lock_irqsave(&scst_mgmt_lock, flags);
-+
-+ if (wait)
-+ sess->shutdown_compl = &c;
-+
-+ spin_unlock_irqrestore(&scst_mgmt_lock, flags);
-+
-+ scst_sess_put(sess);
-+
-+ if (wait) {
-+ TRACE_DBG("Waiting for session %p to complete", sess);
-+ wait_for_completion(&c);
-+ }
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(scst_unregister_session);
-+
-+/**
-+ * scst_unregister_session_non_gpl() - unregister session, non-GPL version
-+ * @sess: session to be unregistered
-+ *
-+ * Unregisters session.
-+ *
-+ * See notes for scst_unregister_session() above.
-+ */
-+void scst_unregister_session_non_gpl(struct scst_session *sess)
-+{
-+ TRACE_ENTRY();
-+
-+ scst_unregister_session(sess, 1, NULL);
-+
-+ TRACE_EXIT();
-+ return;
-+}
-+EXPORT_SYMBOL(scst_unregister_session_non_gpl);
-+
-+static inline int test_mgmt_list(void)
-+{
-+ int res = !list_empty(&scst_sess_init_list) ||
-+ !list_empty(&scst_sess_shut_list) ||
-+ unlikely(kthread_should_stop());
-+ return res;
-+}
-+
-+int scst_global_mgmt_thread(void *arg)
-+{
-+ struct scst_session *sess;
-+
-+ TRACE_ENTRY();
-+
-+ PRINT_INFO("Management thread started, PID %d", current->pid);
-+
-+ current->flags |= PF_NOFREEZE;
-+
-+ set_user_nice(current, -10);
-+
-+ spin_lock_irq(&scst_mgmt_lock);
-+ while (!kthread_should_stop()) {
-+ wait_queue_t wait;
-+ init_waitqueue_entry(&wait, current);
-+
-+ if (!test_mgmt_list()) {
-+ add_wait_queue_exclusive(&scst_mgmt_waitQ, &wait);
-+ for (;;) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (test_mgmt_list())
-+ break;
-+ spin_unlock_irq(&scst_mgmt_lock);
-+ schedule();
-+ spin_lock_irq(&scst_mgmt_lock);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&scst_mgmt_waitQ, &wait);
-+ }
-+
-+ while (!list_empty(&scst_sess_init_list)) {
-+ sess = list_entry(scst_sess_init_list.next,
-+ typeof(*sess), sess_init_list_entry);
-+ TRACE_DBG("Removing sess %p from scst_sess_init_list",
-+ sess);
-+ list_del(&sess->sess_init_list_entry);
-+ spin_unlock_irq(&scst_mgmt_lock);
-+
-+ if (sess->init_phase == SCST_SESS_IPH_INITING)
-+ scst_init_session(sess);
-+ else {
-+ PRINT_CRIT_ERROR("session %p is in "
-+ "scst_sess_init_list, but in unknown "
-+ "init phase %x", sess,
-+ sess->init_phase);
-+ BUG();
-+ }
-+
-+ spin_lock_irq(&scst_mgmt_lock);
-+ }
-+
-+ while (!list_empty(&scst_sess_shut_list)) {
-+ sess = list_entry(scst_sess_shut_list.next,
-+ typeof(*sess), sess_shut_list_entry);
-+ TRACE_DBG("Removing sess %p from scst_sess_shut_list",
-+ sess);
-+ list_del(&sess->sess_shut_list_entry);
-+ spin_unlock_irq(&scst_mgmt_lock);
-+
-+ switch (sess->shut_phase) {
-+ case SCST_SESS_SPH_SHUTDOWN:
-+ BUG_ON(atomic_read(&sess->refcnt) != 0);
-+ scst_free_session_callback(sess);
-+ break;
-+ default:
-+ PRINT_CRIT_ERROR("session %p is in "
-+ "scst_sess_shut_list, but in unknown "
-+ "shut phase %lx", sess,
-+ sess->shut_phase);
-+ BUG();
-+ break;
-+ }
-+
-+ spin_lock_irq(&scst_mgmt_lock);
-+ }
-+ }
-+ spin_unlock_irq(&scst_mgmt_lock);
-+
-+ /*
-+ * If kthread_should_stop() is true, we are guaranteed to be
-+ * on the module unload, so both lists must be empty.
-+ */
-+ BUG_ON(!list_empty(&scst_sess_init_list));
-+ BUG_ON(!list_empty(&scst_sess_shut_list));
-+
-+ PRINT_INFO("Management thread PID %d finished", current->pid);
-+
-+ TRACE_EXIT();
-+ return 0;
-+}
-+
-+/* Called under sess->sess_list_lock */
-+static struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess,
-+ uint64_t tag, bool to_abort)
-+{
-+ struct scst_cmd *cmd, *res = NULL;
-+
-+ TRACE_ENTRY();
-+
-+ /* ToDo: hash list */
-+
-+ TRACE_DBG("%s (sess=%p, tag=%llu)", "Searching in sess cmd list",
-+ sess, (long long unsigned int)tag);
-+
-+ list_for_each_entry(cmd, &sess->sess_cmd_list,
-+ sess_cmd_list_entry) {
-+ if (cmd->tag == tag) {
-+ /*
-+ * We must not count done commands, because
-+ * they were submitted for transmission.
-+ * Otherwise we can have a race, when for
-+ * some reason cmd's release delayed
-+ * after transmission and initiator sends
-+ * cmd with the same tag => it can be possible
-+ * that a wrong cmd will be returned.
-+ */
-+ if (cmd->done) {
-+ if (to_abort) {
-+ /*
-+ * We should return the latest not
-+ * aborted cmd with this tag.
-+ */
-+ if (res == NULL)
-+ res = cmd;
-+ else {
-+ if (test_bit(SCST_CMD_ABORTED,
-+ &res->cmd_flags)) {
-+ res = cmd;
-+ } else if (!test_bit(SCST_CMD_ABORTED,
-+ &cmd->cmd_flags))
-+ res = cmd;
-+ }
-+ }
-+ continue;
-+ } else {
-+ res = cmd;
-+ break;
-+ }
-+ }
-+ }
-+
-+ TRACE_EXIT();
-+ return res;
-+}
-+
-+/**
-+ * scst_find_cmd() - find command by custom comparison function
-+ *
-+ * Finds a command based on user supplied data and comparison
-+ * callback function, that should return true, if the command is found.
-+ * Returns the command on success or NULL otherwise.
-+ */
-+struct scst_cmd *scst_find_cmd(struct scst_session *sess, void *data,
-+ int (*cmp_fn) (struct scst_cmd *cmd,
-+ void *data))
-+{
-+ struct scst_cmd *cmd = NULL;
-+ unsigned long flags = 0;
-+
-+ TRACE_ENTRY();
-+
-+ if (cmp_fn == NULL)
-+ goto out;
-+
-+ spin_lock_irqsave(&sess->sess_list_lock, flags);
-+
-+ TRACE_DBG("Searching in sess cmd list (sess=%p)", sess);
-+ list_for_each_entry(cmd, &sess->sess_cmd_list, sess_cmd_list_entry) {
-+ /*
-+ * We must not count done commands, because they were
-+ * submitted for transmission. Otherwise we can have a race,
-+ * when for some reason cmd's release delayed after
-+ * transmission and initiator sends cmd with the same tag =>
-+ * it can be possible that a wrong cmd will be returned.
-+ */
-+ if (cmd->done)
-+ continue;
-+ if (cmp_fn(cmd, data))
-+ goto out_unlock;
-+ }
-+
-+ cmd = NULL;
-+
-+out_unlock:
-+ spin_unlock_irqrestore(&sess->sess_list_lock, flags);
-+
-+out:
-+ TRACE_EXIT();
-+ return cmd;
-+}
-+EXPORT_SYMBOL(scst_find_cmd);
-+
-+/**